summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/harfbuzz-ng/AUTHORS8
-rw-r--r--src/3rdparty/harfbuzz-ng/COPYING36
-rw-r--r--src/3rdparty/harfbuzz-ng/NEWS797
-rw-r--r--src/3rdparty/harfbuzz-ng/README7
-rw-r--r--src/3rdparty/harfbuzz-ng/THANKS7
-rw-r--r--src/3rdparty/harfbuzz-ng/TODO81
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-blob.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-buffer.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-common.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-deprecated.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-face.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-font.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-layout.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-tag.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-set.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape-plan.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-unicode.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-version.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/config.h26
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh132
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.cc328
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.h127
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh643
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh571
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh202
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc336
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.cc1077
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.h323
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh74
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.cc434
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.h333
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-deprecated.h51
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face-private.hh108
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.cc311
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.h117
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc128
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font-private.hh414
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.cc739
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.h381
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh130
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-object-private.hh227
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh261
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh981
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh149
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh97
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh92
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh1170
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh431
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh1629
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh1427
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh2449
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh296
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc910
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h293
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh247
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc275
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh69
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh134
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh260
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh942
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc356
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc220
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh1443
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh151
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc869
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc1673
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh391
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc534
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh359
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh224
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc384
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc378
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh49
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc456
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh70
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc408
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh87
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc667
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc722
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h59
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot.h49
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-private.hh909
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-private.hh335
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.cc227
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.h152
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh60
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc314
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h89
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.cc275
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.h81
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh43
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh55
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh109
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper.cc109
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh317
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.cc435
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.h357
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh204
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-version.h66
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-warning.cc66
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb.h47
-rw-r--r--src/3rdparty/harfbuzz.pri106
-rw-r--r--src/android/accessibility/accessibility.pro2
-rw-r--r--src/android/accessibility/jar/AndroidManifest.xml7
-rw-r--r--src/android/accessibility/jar/bundledjar.pro3
-rw-r--r--src/android/accessibility/jar/distributedjar.pro2
-rw-r--r--src/android/accessibility/jar/jar.pri14
-rw-r--r--src/android/accessibility/jar/jar.pro2
-rw-r--r--src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java343
-rw-r--r--src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java58
-rw-r--r--src/android/android.pro2
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java19
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java3
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtSurface.java46
-rw-r--r--src/android/java/AndroidManifest.xml1
-rw-r--r--src/concurrent/doc/qtconcurrent.qdocconf3
-rw-r--r--src/concurrent/doc/src/qtconcurrent-module.qdoc1
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in7
-rw-r--r--src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in6
-rw-r--r--src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in6
-rw-r--r--src/corelib/corelib.pro30
-rw-r--r--src/corelib/doc/qtcore.qdocconf5
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp6
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp58
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineoption.cpp44
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineparser.cpp141
-rw-r--r--src/corelib/doc/src/qtcore-index.qdoc2
-rw-r--r--src/corelib/doc/src/qtcore.qdoc5
-rw-r--r--src/corelib/global/qcompilerdetection.h33
-rw-r--r--src/corelib/global/qglobal.cpp10
-rw-r--r--src/corelib/global/qglobal.h15
-rw-r--r--src/corelib/global/qlibraryinfo.cpp23
-rw-r--r--src/corelib/global/qlibraryinfo.h2
-rw-r--r--src/corelib/global/qnamespace.h19
-rw-r--r--src/corelib/global/qnamespace.qdoc25
-rw-r--r--src/corelib/global/qprocessordetection.h26
-rw-r--r--src/corelib/global/qsystemdetection.h11
-rw-r--r--src/corelib/io/qdatastream.cpp4
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdir.cpp61
-rw-r--r--src/corelib/io/qiodevice.cpp4
-rw-r--r--src/corelib/io/qipaddress.cpp60
-rw-r--r--src/corelib/io/qipaddress_p.h2
-rw-r--r--src/corelib/io/qprocess.cpp97
-rw-r--r--src/corelib/io/qprocess.h12
-rw-r--r--src/corelib/io/qprocess_p.h1
-rw-r--r--src/corelib/io/qprocess_unix.cpp81
-rw-r--r--src/corelib/io/qprocess_win.cpp61
-rw-r--r--src/corelib/io/qsettings.cpp2
-rw-r--r--src/corelib/io/qstandardpaths.cpp11
-rw-r--r--src/corelib/io/qstandardpaths.h5
-rw-r--r--src/corelib/io/qurl.cpp874
-rw-r--r--src/corelib/io/qurl.h26
-rw-r--r--src/corelib/io/qurl_p.h3
-rw-r--r--src/corelib/io/qurlidna.cpp5
-rw-r--r--src/corelib/io/qurlquery.cpp57
-rw-r--r--src/corelib/io/qurlrecode.cpp114
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp170
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h23
-rw-r--r--src/corelib/json/qjson_p.h2
-rw-r--r--src/corelib/json/qjsonvalue.cpp25
-rw-r--r--src/corelib/json/qjsonvalue.h3
-rw-r--r--src/corelib/json/qjsonwriter.cpp9
-rw-r--r--src/corelib/kernel/qcore_mac_p.h6
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp61
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry.cpp82
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp2
-rw-r--r--src/corelib/kernel/qmetatype.cpp285
-rw-r--r--src/corelib/kernel/qmetatype.h1134
-rw-r--r--src/corelib/kernel/qobject.cpp62
-rw-r--r--src/corelib/kernel/qobject_p.h7
-rw-r--r--src/corelib/kernel/qobjectdefs.h1
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp9
-rw-r--r--src/corelib/kernel/qvariant.cpp591
-rw-r--r--src/corelib/kernel/qvariant.h299
-rw-r--r--src/corelib/plugin/plugin.pri6
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp12
-rw-r--r--src/corelib/plugin/qlibrary.cpp141
-rw-r--r--src/corelib/plugin/qlibrary_p.h3
-rw-r--r--src/corelib/plugin/qmachparser.cpp218
-rw-r--r--src/corelib/plugin/qmachparser_p.h (renamed from src/plugins/platforms/kms/qkmsudevlistener.h)55
-rw-r--r--src/corelib/plugin/qplugin.h16
-rw-r--r--src/corelib/plugin/qpluginloader.cpp50
-rw-r--r--src/corelib/plugin/qpluginloader.h2
-rw-r--r--src/corelib/thread/qmutex_linux.cpp26
-rw-r--r--src/corelib/thread/qthread.cpp60
-rw-r--r--src/corelib/thread/qthread.h3
-rw-r--r--src/corelib/thread/qthread_p.h1
-rw-r--r--src/corelib/thread/qthread_unix.cpp2
-rw-r--r--src/corelib/thread/qthread_win.cpp2
-rw-r--r--src/corelib/thread/qthreadpool.cpp65
-rw-r--r--src/corelib/thread/qthreadpool.h2
-rw-r--r--src/corelib/thread/qthreadpool_p.h1
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp2
-rw-r--r--src/corelib/tools/qalgorithms.h72
-rw-r--r--src/corelib/tools/qalgorithms.qdoc31
-rw-r--r--src/corelib/tools/qbitarray.cpp40
-rw-r--r--src/corelib/tools/qbitarray.h1
-rw-r--r--src/corelib/tools/qbytearray.cpp1
-rw-r--r--src/corelib/tools/qchar.cpp61
-rw-r--r--src/corelib/tools/qcommandlineoption.cpp308
-rw-r--r--src/corelib/tools/qcommandlineoption.h92
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp896
-rw-r--r--src/corelib/tools/qcommandlineparser.h106
-rw-r--r--src/corelib/tools/qdatetime.cpp1592
-rw-r--r--src/corelib/tools/qdatetime.h29
-rw-r--r--src/corelib/tools/qdatetime_p.h20
-rw-r--r--src/corelib/tools/qeasingcurve.cpp10
-rw-r--r--src/corelib/tools/qharfbuzz_p.h14
-rw-r--r--src/corelib/tools/qhash.h32
-rw-r--r--src/corelib/tools/qlinkedlist.h41
-rw-r--r--src/corelib/tools/qlist.h38
-rw-r--r--src/corelib/tools/qlocale.cpp151
-rw-r--r--src/corelib/tools/qlocale.h3
-rw-r--r--src/corelib/tools/qlocale.qdoc3
-rw-r--r--src/corelib/tools/qlocale_data_p.h2521
-rw-r--r--src/corelib/tools/qlocale_p.h5
-rw-r--r--src/corelib/tools/qlocale_tools.cpp22
-rw-r--r--src/corelib/tools/qmap.h39
-rw-r--r--src/corelib/tools/qpair.h13
-rw-r--r--src/corelib/tools/qpair.qdoc20
-rw-r--r--src/corelib/tools/qscopedpointer.cpp3
-rw-r--r--src/corelib/tools/qscopedpointer.h11
-rw-r--r--src/corelib/tools/qset.h22
-rw-r--r--src/corelib/tools/qsimd.cpp2
-rw-r--r--src/corelib/tools/qstring.cpp38
-rw-r--r--src/corelib/tools/qstring.h4
-rw-r--r--src/corelib/tools/qunicodetables.cpp13108
-rw-r--r--src/corelib/tools/qunicodetables_p.h5
-rw-r--r--src/corelib/tools/qunicodetools.cpp17
-rw-r--r--src/corelib/tools/qvarlengtharray.h13
-rw-r--r--src/corelib/tools/qvector.h26
-rw-r--r--src/corelib/tools/tools.pri4
-rw-r--r--src/dbus/doc/qtdbus.qdocconf5
-rw-r--r--src/dbus/doc/src/qtdbus-module.qdoc1
-rw-r--r--src/dbus/qdbusabstractadaptor.cpp13
-rw-r--r--src/dbus/qdbusconnection_p.h4
-rw-r--r--src/dbus/qdbusintegrator.cpp6
-rw-r--r--src/dbus/qdbusmisc.cpp22
-rw-r--r--src/dbus/qdbuspendingcall.cpp2
-rw-r--r--src/dbus/qdbusxmlgenerator.cpp16
-rw-r--r--src/gui/accessible/qaccessible2_p.h6
-rw-r--r--src/gui/accessible/qaccessiblecache.cpp4
-rw-r--r--src/gui/doc/qtgui.qdocconf3
-rw-r--r--src/gui/doc/snippets/code/doc_src_qtgui.pro4
-rw-r--r--src/gui/doc/src/qtgui.qdoc17
-rw-r--r--src/gui/image/qbmphandler.cpp3
-rw-r--r--src/gui/image/qicon.cpp1
-rw-r--r--src/gui/image/qicon.h4
-rw-r--r--src/gui/image/qiconloader.cpp12
-rw-r--r--src/gui/image/qimage.cpp689
-rw-r--r--src/gui/image/qimage.h8
-rw-r--r--src/gui/image/qimage_p.h3
-rw-r--r--src/gui/image/qimagereader.cpp8
-rw-r--r--src/gui/image/qimagewriter.cpp6
-rw-r--r--src/gui/image/qpicture.cpp4
-rw-r--r--src/gui/image/qpixmap_win.cpp3
-rw-r--r--src/gui/image/qppmhandler.cpp3
-rw-r--r--src/gui/image/qxpmhandler.cpp2
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.cpp5
-rw-r--r--src/gui/kernel/kernel.pri7
-rw-r--r--src/gui/kernel/qevent.cpp87
-rw-r--r--src/gui/kernel/qevent.h9
-rw-r--r--src/gui/kernel/qguiapplication.cpp228
-rw-r--r--src/gui/kernel/qguiapplication.h3
-rw-r--r--src/gui/kernel/qguiapplication_p.h12
-rw-r--r--src/gui/kernel/qkeysequence.cpp227
-rw-r--r--src/gui/kernel/qkeysequence.h4
-rw-r--r--src/gui/kernel/qkeysequence_p.h5
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp51
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h52
-rw-r--r--src/gui/kernel/qplatformintegration.cpp21
-rw-r--r--src/gui/kernel/qplatformintegration.h10
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp20
-rw-r--r--src/gui/kernel/qplatformintegrationfactory_p.h2
-rw-r--r--src/gui/kernel/qplatformintegrationplugin.cpp14
-rw-r--r--src/gui/kernel/qplatformintegrationplugin.h5
-rw-r--r--src/gui/kernel/qplatformservices.cpp5
-rw-r--r--src/gui/kernel/qplatformsessionmanager.cpp (renamed from src/plugins/platforms/kms/qkmsudevlistener.cpp)104
-rw-r--r--src/gui/kernel/qplatformsessionmanager.h (renamed from src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h)96
-rw-r--r--src/gui/kernel/qplatformtheme.cpp278
-rw-r--r--src/gui/kernel/qplatformtheme.h15
-rw-r--r--src/gui/kernel/qplatformtheme_p.h6
-rw-r--r--src/gui/kernel/qsessionmanager.cpp74
-rw-r--r--src/gui/kernel/qsessionmanager_p.h (renamed from src/plugins/platforminputcontexts/maliit/main.cpp)50
-rw-r--r--src/gui/kernel/qshortcutmap.cpp3
-rw-r--r--src/gui/kernel/qstylehints.cpp11
-rw-r--r--src/gui/kernel/qstylehints.h1
-rw-r--r--src/gui/kernel/qtouchdevice.cpp19
-rw-r--r--src/gui/kernel/qtouchdevice.h2
-rw-r--r--src/gui/kernel/qtouchdevice_p.h4
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp27
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h7
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h6
-rw-r--r--src/gui/math3d/qvector2d.cpp19
-rw-r--r--src/gui/math3d/qvector2d.h15
-rw-r--r--src/gui/math3d/qvector3d.cpp19
-rw-r--r--src/gui/math3d/qvector3d.h15
-rw-r--r--src/gui/math3d/qvector4d.cpp19
-rw-r--r--src/gui/math3d/qvector4d.h15
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp21
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp12
-rw-r--r--src/gui/opengl/qopenglfunctions.h3
-rw-r--r--src/gui/painting/painting.pri9
-rw-r--r--src/gui/painting/qblendfunctions.cpp465
-rw-r--r--src/gui/painting/qcolor.cpp43
-rw-r--r--src/gui/painting/qcolor.h3
-rw-r--r--src/gui/painting/qcolor_p.cpp12
-rw-r--r--src/gui/painting/qdrawhelper.cpp206
-rw-r--r--src/gui/painting/qdrawhelper_p.h24
-rw-r--r--src/gui/painting/qimagescale.cpp2
-rw-r--r--src/gui/painting/qmemrotate.cpp5
-rw-r--r--src/gui/painting/qpaintbuffer.cpp6
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp7
-rw-r--r--src/gui/painting/qpainter.cpp12
-rw-r--r--src/gui/painting/qpathclipper.cpp7
-rw-r--r--src/gui/painting/qpathsimplifier.cpp1
-rw-r--r--src/gui/painting/qrasterizer.cpp4
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp9
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.cpp24
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h1
-rw-r--r--src/gui/text/qfontdatabase.cpp56
-rw-r--r--src/gui/text/qfontdatabase.h10
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp2
-rw-r--r--src/gui/text/qfontengine.cpp97
-rw-r--r--src/gui/text/qfontengine_ft.cpp63
-rw-r--r--src/gui/text/qfontengine_ft_p.h9
-rw-r--r--src/gui/text/qfontengine_p.h9
-rw-r--r--src/gui/text/qfontengine_qpf.cpp3
-rw-r--r--src/gui/text/qfontsubset.cpp6
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp13
-rw-r--r--src/gui/text/qplatformfontdatabase.h2
-rw-r--r--src/gui/text/qtextdocument.h2
-rw-r--r--src/gui/text/qtextdocumentwriter.cpp4
-rw-r--r--src/gui/text/qtextengine.cpp242
-rw-r--r--src/gui/text/qtextengine_p.h47
-rw-r--r--src/network/access/qftp.cpp8
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp36
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h4
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp14
-rw-r--r--src/network/access/qhttpnetworkreply.cpp5
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp22
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h4
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp8
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp17
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h2
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp11
-rw-r--r--src/network/access/qnetworkaccessfilebackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessftpbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp171
-rw-r--r--src/network/access/qnetworkaccessmanager.h16
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h16
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp7
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp190
-rw-r--r--src/network/bearer/qnetworkconfiguration.h7
-rw-r--r--src/network/doc/qtnetwork.qdocconf3
-rw-r--r--src/network/doc/src/qtnetwork.qdoc1
-rw-r--r--src/network/kernel/qhostaddress.cpp2
-rw-r--r--src/network/socket/qhttpsocketengine.cpp92
-rw-r--r--src/network/socket/qhttpsocketengine_p.h5
-rw-r--r--src/network/ssl/qssl.cpp10
-rw-r--r--src/network/ssl/qssl.h4
-rw-r--r--src/network/ssl/qsslconfiguration.cpp65
-rw-r--r--src/network/ssl/qsslconfiguration.h4
-rw-r--r--src/network/ssl/qsslconfiguration_p.h6
-rw-r--r--src/network/ssl/qsslcontext.cpp41
-rw-r--r--src/network/ssl/qsslcontext_p.h5
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp38
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp6
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h2
-rw-r--r--src/network/ssl/qsslsocket_p.h4
-rw-r--r--src/opengl/doc/qtopengl.qdocconf5
-rw-r--r--src/opengl/doc/src/qtopengl-module.qdoc1
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_p.h3
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp12
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp8
-rw-r--r--src/platformsupport/eglconvenience/qxlibeglintegration.cpp17
-rw-r--r--src/platformsupport/eventdispatchers/eventdispatchers.pri8
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm (renamed from src/plugins/platforms/ios/qioseventdispatcher.mm)203
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h (renamed from src/plugins/platforms/ios/qioseventdispatcher.h)115
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp4
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm173
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h20
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm32
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h1
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp7
-rw-r--r--src/platformsupport/services/genericunix/qgenericunixservices.cpp26
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp62
-rw-r--r--src/plugins/accessible/widgets/itemviews.cpp9
-rw-r--r--src/plugins/accessible/widgets/itemviews.h1
-rw-r--r--src/plugins/bearer/blackberry/qbbengine.cpp7
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp4
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp4
-rw-r--r--src/plugins/platforminputcontexts/maliit/contextadaptor.cpp158
-rw-r--r--src/plugins/platforminputcontexts/maliit/contextadaptor.h148
-rw-r--r--src/plugins/platforminputcontexts/maliit/maliit.json3
-rw-r--r--src/plugins/platforminputcontexts/maliit/maliit.pro19
-rw-r--r--src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp583
-rw-r--r--src/plugins/platforminputcontexts/maliit/serveraddressproxy.h84
-rw-r--r--src/plugins/platforminputcontexts/maliit/serverproxy.h166
-rw-r--r--src/plugins/platforminputcontexts/platforminputcontexts.pro2
-rw-r--r--src/plugins/platforms/android/src/androidjniaccessibility.cpp260
-rw-r--r--src/plugins/platforms/android/src/androidjniaccessibility.h (renamed from src/plugins/platforms/kms/qkmsudevhandler.cpp)16
-rw-r--r--src/plugins/platforms/android/src/androidjniinput.cpp18
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp24
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.h2
-rw-r--r--src/plugins/platforms/android/src/androidplatformplugin.cpp2
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp6
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp (renamed from src/plugins/platforminputcontexts/maliit/serveraddressproxy.cpp)22
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformaccessibility.h (renamed from src/plugins/platforms/kms/qkmsudevdrmhandler.h)23
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.cpp19
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.h10
-rw-r--r--src/plugins/platforms/android/src/qandroidsystemlocale.cpp179
-rw-r--r--src/plugins/platforms/android/src/qandroidsystemlocale.h67
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp13
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformwindow.h2
-rw-r--r--src/plugins/platforms/android/src/src.pri10
-rw-r--r--src/plugins/platforms/cocoa/main.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm128
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.h11
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm265
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm30
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaservices.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm4
-rwxr-xr-xsrc/plugins/platforms/cocoa/qcocoasystemtrayicon.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm3
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm207
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm10
-rw-r--r--src/plugins/platforms/directfb/main.cpp2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp8
-rw-r--r--src/plugins/platforms/eglfs/main.cpp2
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp36
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h3
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp6
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h7
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp31
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h4
-rw-r--r--src/plugins/platforms/ios/ios.pro40
-rw-r--r--src/plugins/platforms/ios/plugin.mm6
-rw-r--r--src/plugins/platforms/ios/plugin.pro36
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.h4
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.mm59
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.h (renamed from src/plugins/platforms/kms/qkmsudevhandler.h)24
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.mm162
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm12
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.h1
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm11
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h3
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm12
-rw-r--r--src/plugins/platforms/ios/qiosmain_dummy.mm (renamed from src/plugins/platforminputcontexts/maliit/serverproxy.cpp)20
-rw-r--r--src/plugins/platforms/ios/qiosmain_wrapper.mm (renamed from src/plugins/platforms/kms/qkmsudevdrmhandler.cpp)34
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm32
-rw-r--r--src/plugins/platforms/ios/qtmain.mm94
-rw-r--r--src/plugins/platforms/ios/qtmain.pro8
-rw-r--r--src/plugins/platforms/kms/kms.pro6
-rw-r--r--src/plugins/platforms/kms/main.cpp2
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp43
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h14
-rw-r--r--src/plugins/platforms/linuxfb/main.cpp2
-rw-r--r--src/plugins/platforms/minimal/main.cpp2
-rw-r--r--src/plugins/platforms/minimalegl/main.cpp2
-rw-r--r--src/plugins/platforms/offscreen/main.cpp2
-rw-r--r--src/plugins/platforms/offscreen/offscreen.pro1
-rw-r--r--src/plugins/platforms/openwfd/main.cpp2
-rw-r--r--src/plugins/platforms/qnx/main.cpp3
-rw-r--r--src/plugins/platforms/qnx/main.h2
-rw-r--r--src/plugins/platforms/qnx/qnx.pro31
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper.h28
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp217
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp (renamed from src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp)36
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.cpp289
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.h110
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp154
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.h15
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp34
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h15
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp27
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp27
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h1
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxtheme.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp148
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h19
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp8
-rw-r--r--src/plugins/platforms/windows/main.cpp6
-rw-r--r--src/plugins/platforms/windows/qtwindows_additional.h4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h10
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp45
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h5
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp235
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp141
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp473
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h142
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp121
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h3
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp75
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/plugins/platforms/windows/windows.pro6
-rw-r--r--src/plugins/platforms/xcb/main.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp33
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h15
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp290
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp30
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp47
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h13
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp180
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.h87
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp31
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro6
-rw-r--r--src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp28
-rw-r--r--src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h12
-rw-r--r--src/printsupport/doc/qtprintsupport.qdocconf3
-rw-r--r--src/printsupport/doc/src/qtprintsupport-module.qdoc1
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp3
-rw-r--r--src/printsupport/kernel/qprinter.cpp4
-rw-r--r--src/sql/doc/qtsql.qdocconf3
-rw-r--r--src/sql/doc/src/qtsql.qdoc1
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp18
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp28
-rw-r--r--src/src.pro6
-rw-r--r--src/testlib/doc/qttestlib.qdocconf3
-rw-r--r--src/testlib/doc/src/qttest.qdoc1
-rw-r--r--src/testlib/doc/src/qttestlib-manual.qdoc3
-rw-r--r--src/testlib/qabstracttestlogger.cpp10
-rw-r--r--src/testlib/qtestcase.cpp35
-rw-r--r--src/testlib/qtestresult.cpp8
-rw-r--r--src/tools/bootstrap/bootstrap.pro2
-rw-r--r--src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp12
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp4
-rw-r--r--src/tools/qdoc/codemarker.cpp2
-rw-r--r--src/tools/qdoc/codeparser.cpp57
-rw-r--r--src/tools/qdoc/codeparser.h2
-rw-r--r--src/tools/qdoc/config.cpp43
-rw-r--r--src/tools/qdoc/config.h9
-rw-r--r--src/tools/qdoc/cppcodemarker.cpp59
-rw-r--r--src/tools/qdoc/cppcodeparser.cpp381
-rw-r--r--src/tools/qdoc/cppcodeparser.h14
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.cpp70
-rw-r--r--src/tools/qdoc/doc.cpp66
-rw-r--r--src/tools/qdoc/doc.h11
-rw-r--r--src/tools/qdoc/doc/config/qdoc.qdocconf2
-rw-r--r--src/tools/qdoc/generator.cpp78
-rw-r--r--src/tools/qdoc/generator.h27
-rw-r--r--src/tools/qdoc/helpprojectwriter.cpp67
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp590
-rw-r--r--src/tools/qdoc/htmlgenerator.h20
-rw-r--r--src/tools/qdoc/main.cpp24
-rw-r--r--src/tools/qdoc/node.cpp160
-rw-r--r--src/tools/qdoc/node.h67
-rw-r--r--src/tools/qdoc/puredocparser.cpp81
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp2
-rw-r--r--src/tools/qdoc/qdocindexfiles.cpp59
-rw-r--r--src/tools/qdoc/qdoctagfiles.cpp10
-rw-r--r--src/tools/qdoc/qmlcodeparser.cpp67
-rw-r--r--src/tools/qdoc/qmlcodeparser.h4
-rw-r--r--src/tools/qdoc/qmlparser/qqmljs.g2
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsparser_p.h2
-rw-r--r--src/tools/qdoc/qmlvisitor.cpp219
-rw-r--r--src/tools/qdoc/qmlvisitor.h11
-rw-r--r--src/tools/qdoc/tokenizer.cpp6
-rw-r--r--src/tools/qdoc/tree.cpp2
-rw-r--r--src/tools/qdoc/tree.h1
-rw-r--r--src/tools/rcc/main.cpp188
-rw-r--r--src/tools/rcc/rcc.cpp6
-rw-r--r--src/tools/uic/main.cpp146
-rw-r--r--src/tools/uic/option.h1
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp244
-rw-r--r--src/widgets/dialogs/qcolordialog.h4
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h8
-rw-r--r--src/widgets/dialogs/qdialog.cpp4
-rw-r--r--src/widgets/dialogs/qdialog_p.h2
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp487
-rw-r--r--src/widgets/dialogs/qfiledialog.h68
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h40
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp2
-rw-r--r--src/widgets/dialogs/qfileinfogatherer_p.h8
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp6
-rw-r--r--src/widgets/dialogs/qfilesystemmodel_p.h2
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp28
-rw-r--r--src/widgets/dialogs/qfontdialog.h6
-rw-r--r--src/widgets/dialogs/qinputdialog.cpp112
-rw-r--r--src/widgets/dialogs/qinputdialog.h9
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp124
-rw-r--r--src/widgets/doc/qtwidgets.qdocconf3
-rw-r--r--src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp11
-rw-r--r--src/widgets/doc/src/qtwidgets-examples.qdoc2
-rw-r--r--src/widgets/doc/src/qtwidgets.qdoc1
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp6
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp5
-rw-r--r--src/widgets/graphicsview/qgridlayoutengine.cpp9
-rw-r--r--src/widgets/itemviews/itemviews.pri1
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp20
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h2
-rw-r--r--src/widgets/itemviews/qcolumnview.cpp11
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp93
-rw-r--r--src/widgets/itemviews/qfileiconprovider.h14
-rw-r--r--src/widgets/itemviews/qfileiconprovider_p.h87
-rw-r--r--src/widgets/itemviews/qheaderview.cpp155
-rw-r--r--src/widgets/itemviews/qheaderview.h8
-rw-r--r--src/widgets/itemviews/qheaderview_p.h21
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp7
-rw-r--r--src/widgets/itemviews/qlistview.cpp8
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp10
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.cpp7
-rw-r--r--src/widgets/itemviews/qtableview.cpp223
-rw-r--r--src/widgets/itemviews/qtableview.h2
-rw-r--r--src/widgets/itemviews/qtableview_p.h2
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp4
-rw-r--r--src/widgets/itemviews/qtreeview.cpp207
-rw-r--r--src/widgets/itemviews/qtreeview.h5
-rw-r--r--src/widgets/itemviews/qtreeview_p.h14
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp10
-rw-r--r--src/widgets/kernel/qapplication.cpp73
-rw-r--r--src/widgets/kernel/qapplication_p.h4
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp1
-rw-r--r--src/widgets/kernel/qlayout.cpp4
-rw-r--r--src/widgets/kernel/qlayoutengine.cpp31
-rw-r--r--src/widgets/kernel/qlayoutitem.cpp2
-rw-r--r--src/widgets/kernel/qsizepolicy.h5
-rw-r--r--src/widgets/kernel/qsizepolicy.qdoc17
-rw-r--r--src/widgets/kernel/qtooltip.cpp36
-rw-r--r--src/widgets/kernel/qtooltip.h2
-rw-r--r--src/widgets/kernel/qwidget.cpp63
-rw-r--r--src/widgets/kernel/qwidget.h3
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp2
-rw-r--r--src/widgets/styles/images/cleartext-16.pngbin0 -> 760 bytes
-rw-r--r--src/widgets/styles/qcommonstyle.cpp35
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp3
-rw-r--r--src/widgets/styles/qstyle.cpp17
-rw-r--r--src/widgets/styles/qstyle.h5
-rw-r--r--src/widgets/styles/qstyle.qrc1
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp32
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp6
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp150
-rw-r--r--src/widgets/util/util.pri1
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp20
-rw-r--r--src/widgets/widgets/qabstractbutton_p.h1
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp96
-rw-r--r--src/widgets/widgets/qabstractscrollarea.h12
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h4
-rw-r--r--src/widgets/widgets/qbuttongroup.cpp21
-rw-r--r--src/widgets/widgets/qbuttongroup.h3
-rw-r--r--src/widgets/widgets/qcombobox.cpp33
-rw-r--r--src/widgets/widgets/qcombobox.h3
-rw-r--r--src/widgets/widgets/qcombobox_p.h4
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp15
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.h3
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp99
-rw-r--r--src/widgets/widgets/qlineedit.cpp124
-rw-r--r--src/widgets/widgets/qlineedit.h25
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp171
-rw-r--r--src/widgets/widgets/qlineedit_p.h82
-rw-r--r--src/widgets/widgets/qmdiarea.cpp6
-rw-r--r--src/widgets/widgets/qpushbutton_p.h5
-rw-r--r--src/widgets/widgets/qscrollarea.cpp12
-rw-r--r--src/widgets/widgets/qscrollarea.h2
-rw-r--r--src/widgets/widgets/qscrollbar.cpp5
-rw-r--r--src/widgets/widgets/qspinbox.cpp64
-rw-r--r--src/widgets/widgets/qspinbox.h3
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp16
-rw-r--r--src/widgets/widgets/qsplashscreen.h1
-rw-r--r--src/widgets/widgets/qsplitter.cpp19
-rw-r--r--src/widgets/widgets/qsplitter_p.h3
-rw-r--r--src/widgets/widgets/qtabbar.cpp46
-rw-r--r--src/widgets/widgets/qtabbar.h3
-rw-r--r--src/widgets/widgets/qtabbar_p.h5
-rw-r--r--src/widgets/widgets/qtabwidget.cpp24
-rw-r--r--src/widgets/widgets/qtabwidget.h2
-rw-r--r--src/widgets/widgets/qtextedit.cpp36
-rw-r--r--src/widgets/widgets/qtextedit.h4
-rw-r--r--src/widgets/widgets/qtextedit_p.h2
-rw-r--r--src/widgets/widgets/qwidgetanimator.cpp28
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp4
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp13
-rw-r--r--src/xml/doc/qtxml.qdocconf3
-rw-r--r--src/xml/doc/src/qtxml.qdoc1
713 files changed, 62880 insertions, 15006 deletions
diff --git a/src/3rdparty/harfbuzz-ng/AUTHORS b/src/3rdparty/harfbuzz-ng/AUTHORS
new file mode 100644
index 0000000000..c611d7d476
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/AUTHORS
@@ -0,0 +1,8 @@
+Behdad Esfahbod
+Simon Hausmann
+Martin Hosken
+Jonathan Kew
+Lars Knoll
+Werner Lemberg
+Owen Taylor
+David Turner
diff --git a/src/3rdparty/harfbuzz-ng/COPYING b/src/3rdparty/harfbuzz-ng/COPYING
new file mode 100644
index 0000000000..9d1056f40b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/COPYING
@@ -0,0 +1,36 @@
+HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
+For parts of HarfBuzz that are licensed under different licenses see individual
+files names COPYING in subdirectories where applicable.
+
+Copyright © 2010,2011,2012 Google, Inc.
+Copyright © 2012 Mozilla Foundation
+Copyright © 2011 Codethink Limited
+Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
+Copyright © 2009 Keith Stribley
+Copyright © 2009 Martin Hosken and SIL International
+Copyright © 2007 Chris Wilson
+Copyright © 2006 Behdad Esfahbod
+Copyright © 2005 David Turner
+Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
+Copyright © 1998-2004 David Turner and Werner Lemberg
+
+For full copyright notices consult the individual files in the package.
+
+
+Permission is hereby granted, without written agreement and without
+license or royalty fees, to use, copy, modify, and distribute this
+software and its documentation for any purpose, provided that the
+above copyright notice and the following two paragraphs appear in
+all copies of this software.
+
+IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS
new file mode 100644
index 0000000000..dc89614e07
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/NEWS
@@ -0,0 +1,797 @@
+Overview of changes leading to 0.9.20
+Thursday, August 29, 2013
+=====================================
+
+General:
+- Misc substitute_closure() fixes.
+- Build fixes.
+
+Documentation:
+- gtk-doc boilerplate integrated. Docs are built now, but
+ contain no contents. By next release hopefully we have
+ some content in. Enable using --enable-gtk-doc.
+
+GObject and Introspection:
+- Added harfbuzz-gobject library (hb-gobject.h) that has type
+ bindings for all HarfBuzz objects and enums. Enable using
+ --with-gobject.
+- Added gobject-introspection boilerplate. Nothing useful
+ right now. Work in progress. Gets enabled automatically if
+ --with-gobject is used. Override with --disable-introspection.
+
+OpenType shaper:
+- Apply 'mark' in Myanmar shaper.
+- Don't apply 'dlig' by default.
+
+Uniscribe shaper:
+- Support user features.
+- Fix loading of fonts that are also installed on the system.
+- Fix shaping of Arabic Presentation Forms.
+- Fix build with wide chars.
+
+CoreText shaper:
+- Support user features.
+
+Source changes:
+- hb_face_t code moved to hb-face.h / hb-face.cc.
+- Added hb-deprecated.h.
+
+API changes:
+- Added HB_DISABLE_DEPRECATED.
+- Deprecated HB_SCRIPT_CANADIAN_ABORIGINAL; replaced by
+ HB_SCRIPT_CANADIAN_SYLLABICS.
+- Deprecated HB_BUFFER_FLAGS_DEFAULT; replaced by
+ HB_BUFFER_FLAG_DEFAULT.
+- Deprecated HB_BUFFER_SERIALIZE_FLAGS_DEFAULT; replaced by
+ HB_BUFFER_SERIALIZE_FLAG_DEFAULT.
+
+
+Overview of changes leading to 0.9.19
+Tuesday, July 16, 2013
+=====================================
+
+- Build fixes.
+- Better handling of multiple variation selectors in a row.
+- Pass on variation selector to GSUB if not consumed by cmap.
+- Fix undefined memory access.
+- Add Javanese config to Indic shaper.
+- Misc bug fixes.
+
+Overview of changes leading to 0.9.18
+Tuesday, May 28, 2013
+=====================================
+
+New build system:
+
+- All unneeded code is all disabled by default,
+
+- Uniscribe and CoreText shapers can be enabled with their --with options,
+
+- icu_le and old shapers cannot be enabled for now,
+
+- glib, freetype, and cairo will be detected automatically.
+ They can be force on/off'ed with their --with options,
+
+- icu and graphite2 are default off, can be enabled with their --with
+ options,
+
+Moreover, ICU support is now build into a separate library:
+libharfbuzz-icu.so, and a new harfbuzz-icu.pc is shipped for it.
+Distros can enable ICU now without every application on earth
+getting linked to via libharfbuzz.so.
+
+For distros I recommend that they make sure they are building --with-glib
+--with-freetype --with-cairo, --with-icu, and optionally --with-graphite2;
+And package harfbuzz and harfbuzz-icu separately.
+
+
+Overview of changes leading to 0.9.17
+Monday, May 20, 2013
+=====================================
+
+- Build fixes.
+- Fix bug in hb_set_get_min().
+- Fix regression with Arabic mark positioning / width-zeroing.
+
+Overview of changes leading to 0.9.16
+Friday, April 19, 2013
+=====================================
+
+- Major speedup in OpenType lookup processing. With the Amiri
+ Arabic font, this release is over 3x faster than previous
+ release. All scripts / languages should see this speedup.
+
+- New --num-iterations option for hb-shape / hb-view; useful for
+ profiling.
+
+Overview of changes leading to 0.9.15
+Friday, April 05, 2013
+=====================================
+
+- Build fixes.
+- Fix crasher in graphite2 shaper.
+- Fix Arabic mark width zeroing regression.
+- Don't compose Hangul jamo into Unicode syllables.
+
+
+Overview of changes leading to 0.9.14
+Thursday, March 21, 2013
+=====================================
+
+- Build fixes.
+- Fix time-consuming sanitize with malicious fonts.
+- Implement hb_buffer_deserialize_glyphs() for both json and text.
+- Do not ignore Hangul filler characters.
+- Indic fixes:
+ * Fix Malayalam pre-base reordering interaction with post-forms.
+ * Further adjust ZWJ handling. Should fix known regressions from
+ 0.9.13.
+
+
+Overview of changes leading to 0.9.13
+Thursday, February 25, 2013
+=====================================
+
+- Build fixes.
+- Ngapi HarfBuzz Hackfest in London (February 2013):
+ * Fixed all known Indic bugs,
+ * New Win8-style Myanmar shaper,
+ * New South-East Asian shaper for Tai Tham, Cham, and New Tai Lue,
+ * Smartly ignore Default_Ignorable characters (joiners, etc) wheb
+ matching GSUB/GPOS lookups,
+ * Fix 'Phags-Pa U+A872 shaping,
+ * Fix partial disabling of default-on features,
+ * Allow disabling of TrueType kerning.
+- Fix possible crasher with broken fonts with overlapping tables.
+- Removed generated files from git again. So, one needs ragel to
+ bootstrap from the git tree.
+
+API changes:
+- hb_shape() and related APIs now abort if buffer direction is
+ HB_DIRECTION_INVALID. Previously, hb_shape() was calling
+ hb_buffer_guess_segment_properties() on the buffer before
+ shaping. The heuristics in that function are fragile. If the
+ user really wants the old behvaior, they can call that function
+ right before calling hb_shape() to get the old behavior.
+- hb_blob_create_sub_blob() always creates sub-blob with
+ HB_MEMORY_MODE_READONLY. See comments for the reason.
+
+
+Overview of changes leading to 0.9.12
+Thursday, January 18, 2013
+=====================================
+
+- Build fixes for Sun compiler.
+- Minor bug fix.
+
+Overview of changes leading to 0.9.11
+Thursday, January 10, 2013
+=====================================
+
+- Build fixes.
+- Fix GPOS mark attachment with null Anchor offsets.
+- [Indic] Fix old-spec reordering of viramas if sequence ends in one.
+- Fix multi-threaded shaper data creation crash.
+- Add atomic ops for Solaris.
+
+API changes:
+- Rename hb_buffer_clear() to hb_buffer_clear_contents().
+
+
+Overview of changes leading to 0.9.10
+Thursday, January 3, 2013
+=====================================
+
+- [Indic] Fixed rendering of Malayalam dot-reph
+- Updated OT language tags.
+- Updated graphite2 backend.
+- Improved hb_ot_layout_get_size_params() logic.
+- Improve hb-shape/hb-view help output.
+- Fixed hb-set.h implementation to not crash.
+- Fixed various issues with hb_ot_layout_collect_lookups().
+- Various build fixes.
+
+New API:
+
+hb_graphite2_face_get_gr_face()
+hb_graphite2_font_get_gr_font()
+hb_coretext_face_get_cg_font()
+
+Modified API:
+
+hb_ot_layout_get_size_params()
+
+
+Overview of changes leading to 0.9.9
+Wednesday, December 5, 2012
+====================================
+
+- Fix build on Windows.
+- Minor improvements.
+
+
+Overview of changes leading to 0.9.8
+Tuesday, December 4, 2012
+====================================
+
+
+- Actually implement hb_shape_plan_get_shaper ().
+- Make UCDB data tables const.
+- Lots of internal refactoring in OTLayout tables.
+- Flesh out hb_ot_layout_lookup_collect_glyphs().
+
+New API:
+
+hb_ot_layout_collect_lookups()
+hb_ot_layout_get_size_params()
+
+
+Overview of changes leading to 0.9.7
+Sunday, November 21, 2012
+====================================
+
+
+HarfBuzz "All-You-Can-Eat-Sushi" (aka Vancouver) Hackfest and follow-on fixes.
+
+- Fix Arabic contextual joining using pre-context text.
+- Fix Sinhala "split matra" mess.
+- Fix Khmer shaping with broken fonts.
+- Implement Thai "PUA" shaping for old fonts.
+- Do NOT route Kharoshthi script through the Indic shaper.
+- Disable fallback positioning for Indic and Thai shapers.
+- Misc fixes.
+
+
+hb-shape / hb-view changes:
+
+- Add --text-before and --text-after
+- Add --bot / --eot / --preserve-default-ignorables
+- hb-shape --output-format=json
+
+
+New API:
+
+hb_buffer_clear()
+
+hb_buffer_flags_t
+
+HB_BUFFER_FLAGS_DEFAULT
+HB_BUFFER_FLAG_BOT
+HB_BUFFER_FLAG_EOT
+HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES
+
+hb_buffer_set_flags()
+hb_buffer_get_flags()
+
+HB_BUFFER_SERIALIZE_FLAGS
+hb_buffer_serialize_glyphs()
+hb_buffer_deserialize_glyphs()
+hb_buffer_serialize_list_formats()
+
+hb_set_add_range()
+hb_set_del_range()
+hb_set_get_population()
+hb_set_next_range()
+
+hb_face_[sg]et_glyph_count()
+
+hb_segment_properties_t
+HB_SEGMENT_PROPERTIES_DEFAULT
+hb_segment_properties_equal()
+hb_segment_properties_hash()
+
+hb_buffer_set_segment_properties()
+hb_buffer_get_segment_properties()
+
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class()
+hb_ot_layout_get_glyphs_in_class()
+
+hb_shape_plan_t
+hb_shape_plan_create()
+hb_shape_plan_create_cached()
+hb_shape_plan_get_empty()
+hb_shape_plan_reference()
+hb_shape_plan_destroy()
+hb_shape_plan_set_user_data()
+hb_shape_plan_get_user_data()
+hb_shape_plan_execute()
+hb_shape_plan_get_shaper()
+
+hb_ot_shape_plan_collect_lookups()
+
+
+API changes:
+
+- Remove "mask" parameter from hb_buffer_add().
+- Rename hb_ot_layout_would_substitute_lookup() and hb_ot_layout_substitute_closure_lookup().
+- hb-set.h API const correction.
+- Renamed hb_set_min/max() to hb_set_get_min/max().
+- Rename hb_ot_layout_feature_get_lookup_indexes() to hb_ot_layout_feature_get_lookups().
+- Rename hb_buffer_guess_properties() to hb_buffer_guess_segment_properties().
+
+
+
+Overview of changes leading to 0.9.6
+Sunday, November 13, 2012
+====================================
+
+- Don't clear pre-context text if no new context is provided.
+- Fix ReverseChainingSubstLookup, which was totally borked.
+- Adjust output format of hb-shape a bit.
+- Include config.h.in in-tree. Makes it easier for alternate build systems.
+- Fix hb_buffer_set_length(buffer, 0) invalid memory allocation.
+- Use ICU LayoutEngine's C API instead of C++. Avoids much headache.
+- Drop glyphs for all of Unicode Default_Ignorable characters.
+- Misc build fixes.
+
+Arabic shaper:
+- Enable 'dlig' and 'mset' features in Arabic shaper.
+- Implement 'Phags-pa shaping, improve Mongolian.
+
+Indic shaper:
+- Decompose Sinhala split matras the way old HarfBuzz / Pango did.
+- Initial support for Consonant Medials.
+- Start adding new-style Myanmar shaping.
+- Make reph and 'pref' logic introspect the font.
+- Route Meetei-Mayek through the Indic shaper.
+- Don't apply 'liga' in Indic shaper.
+- Improve Malayalam pre-base reordering Ra interaction with Chillus.
+
+
+
+Overview of changes leading to 0.9.5
+Sunday, October 14, 2012
+====================================
+
+- Synthetic-GSUB Arabic fallback shaping.
+
+- Misc Indic improvements.
+
+- Add build system support for pthread.
+
+- Imported UCDN for in-tree Unicode callbacks implementation.
+
+- Context-aware Arabic joining.
+
+- Misc other fixes.
+
+- New API:
+
+ hb_feature_to/from-string()
+ hb_buffer_[sg]et_content_type()
+
+
+
+Overview of changes leading to 0.9.4
+Tuesday, Sep 03, 2012
+====================================
+
+- Indic improvements with old-spec Malayalam.
+
+- Better fallback glyph positioning, specially with Thai / Lao marks.
+
+- Implement dotted-circle insertion.
+
+- Better Arabic fallback shaping / ligation.
+
+- Added ICU LayoutEngine backend for testing. Call it by the 'icu_le' name.
+
+- Misc fixes.
+
+
+
+Overview of changes leading to 0.9.3
+Friday, Aug 18, 2012
+====================================
+
+- Fixed fallback mark positioning for left-to-right text.
+
+- Improve mark positioning for the remaining combining classes.
+
+- Unbreak Thai and fallback Arabic shaping.
+
+- Port Arabic shaper to shape-plan caching.
+
+- Use new ICU normalizer functions.
+
+
+
+Overview of changes leading to 0.9.2
+Friday, Aug 10, 2012
+====================================
+
+- Over a thousand commits! This is the first major release of HarfBuzz.
+
+- HarfBuzz is feature-complete now! It should be in par, or better, than
+ both Pango's shapers and old HarfBuzz / Qt shapers.
+
+- New Indic shaper, supporting main Indic scripts, Sinhala, and Khmer.
+
+- Improved Arabic shaper, with fallback Arabic shaping, supporting Arabic,
+ Sinhala, N'ko, Mongolian, and Mandaic.
+
+- New Thai / Lao shaper.
+
+- Tibetan / Hangul support in the generic shaper.
+
+- Synthetic GDEF support for fonts without a GDEF table.
+
+- Fallback mark positioning for fonts without a GPOS table.
+
+- Unicode normalization shaping heuristic during glyph mapping.
+
+- New experimental Graphite2 backend.
+
+- New Uniscribe backend (primarily for testing).
+
+- New CoreText backend (primarily for testing).
+
+- Major optimization and speedup.
+
+- Test suites and testing infrastructure (work in progress).
+
+- Greatly improved hb-view cmdline tool.
+
+- hb-shape cmdline tool.
+
+- Unicode 6.1 support.
+
+Summary of API changes:
+
+o Changed API:
+
+ - Users are expected to only include main header files now (ie. hb.h,
+ hb-glib.h, hb-ft.h, ...)
+
+ - All struct tag names had their initial underscore removed.
+ Ie. "struct _hb_buffer_t" is "struct hb_buffer_t" now.
+
+ - All set_user_data() functions now take a "replace" boolean parameter.
+
+ - hb_buffer_create() takes zero arguments now.
+ Use hb_buffer_pre_allocate() to pre-allocate.
+
+ - hb_buffer_add_utf*() now accept -1 for length parameteres,
+ meaning "nul-terminated".
+
+ - hb_direction_t enum values changed.
+
+ - All *_from_string() APIs now take a length parameter to allow for
+ non-nul-terminated strings. A -1 length means "nul-terminated".
+
+ - Typedef for hb_language_t changed.
+
+ - hb_get_table_func_t renamed to hb_reference_table_func_t.
+
+ - hb_ot_layout_table_choose_script()
+
+ - Various renames in hb-unicode.h.
+
+o New API:
+
+ - hb_buffer_guess_properties()
+ Automatically called by hb_shape().
+
+ - hb_buffer_normalize_glyphs()
+
+ - hb_tag_from_string()
+
+ - hb-coretext.h
+
+ - hb-uniscribe.h
+
+ - hb_face_reference_blob()
+ - hb_face_[sg]et_index()
+ - hb_face_set_upem()
+
+ - hb_font_get_glyph_name_func_t
+ hb_font_get_glyph_from_name_func_t
+ hb_font_funcs_set_glyph_name_func()
+ hb_font_funcs_set_glyph_from_name_func()
+ hb_font_get_glyph_name()
+ hb_font_get_glyph_from_name()
+ hb_font_glyph_to_string()
+ hb_font_glyph_from_string()
+
+ - hb_font_set_funcs_data()
+
+ - hb_ft_font_set_funcs()
+ - hb_ft_font_get_face()
+
+ - hb-gobject.h (work in progress)
+
+ - hb_ot_shape_glyphs_closure()
+ hb_ot_layout_substitute_closure_lookup()
+
+ - hb-set.h
+
+ - hb_shape_full()
+
+ - hb_unicode_combining_class_t
+
+ - hb_unicode_compose_func_t
+ hb_unicode_decompose_func_t
+ hb_unicode_decompose_compatibility_func_t
+ hb_unicode_funcs_set_compose_func()
+ hb_unicode_funcs_set_decompose_func()
+ hb_unicode_funcs_set_decompose_compatibility_func()
+ hb_unicode_compose()
+ hb_unicode_decompose()
+ hb_unicode_decompose_compatibility()
+
+o Removed API:
+
+ - hb_ft_get_font_funcs()
+
+ - hb_ot_layout_substitute_start()
+ hb_ot_layout_substitute_lookup()
+ hb_ot_layout_substitute_finish()
+ hb_ot_layout_position_start()
+ hb_ot_layout_position_lookup()
+ hb_ot_layout_position_finish()
+
+
+
+Overview of changes leading to 0.6.0
+Friday, May 27, 2011
+====================================
+
+- Vertical text support in GPOS
+- Almost all API entries have unit tests now, under test/
+- All thread-safety issues are fixed
+
+Summary of API changes follows.
+
+
+* Simple Types API:
+
+ o New API:
+ HB_LANGUAGE_INVALID
+ hb_language_get_default()
+ hb_direction_to_string()
+ hb_direction_from_string()
+ hb_script_get_horizontal_direction()
+ HB_UNTAG()
+
+ o Renamed API:
+ hb_category_t renamed to hb_unicode_general_category_t
+
+ o Changed API:
+ hb_language_t is a typed pointers now
+
+ o Removed API:
+ HB_TAG_STR()
+
+
+* Use ISO 15924 tags for hb_script_t:
+
+ o New API:
+ hb_script_from_iso15924_tag()
+ hb_script_to_iso15924_tag()
+ hb_script_from_string()
+
+ o Changed API:
+ HB_SCRIPT_* enum members changed value.
+
+
+* Buffer API streamlined:
+
+ o New API:
+ hb_buffer_reset()
+ hb_buffer_set_length()
+ hb_buffer_allocation_successful()
+
+ o Renamed API:
+ hb_buffer_ensure() renamed to hb_buffer_pre_allocate()
+ hb_buffer_add_glyph() renamed to hb_buffer_add()
+
+ o Removed API:
+ hb_buffer_clear()
+ hb_buffer_clear_positions()
+
+ o Changed API:
+ hb_buffer_get_glyph_infos() takes an out length parameter now
+ hb_buffer_get_glyph_positions() takes an out length parameter now
+
+
+* Blob API streamlined:
+
+ o New API:
+ hb_blob_get_data()
+ hb_blob_get_data_writable()
+
+ o Renamed API:
+ hb_blob_create_empty() renamed to hb_blob_get_empty()
+
+ o Removed API:
+ hb_blob_lock()
+ hb_blob_unlock()
+ hb_blob_is_writable()
+ hb_blob_try_writable()
+
+ o Changed API:
+ hb_blob_create() takes user_data before destroy now
+
+
+* Unicode functions API:
+
+ o Unicode function vectors can subclass other unicode function vectors now.
+ Unimplemented callbacks in the subclass automatically chainup to the parent.
+
+ o All hb_unicode_funcs_t callbacks take a user_data now. Their setters
+ take a user_data and its respective destroy callback.
+
+ o New API:
+ hb_unicode_funcs_get_empty()
+ hb_unicode_funcs_get_default()
+ hb_unicode_funcs_get_parent()
+
+ o Changed API:
+ hb_unicode_funcs_create() now takes a parent_funcs.
+
+ o Removed func getter functions:
+ hb_unicode_funcs_get_mirroring_func()
+ hb_unicode_funcs_get_general_category_func()
+ hb_unicode_funcs_get_script_func()
+ hb_unicode_funcs_get_combining_class_func()
+ hb_unicode_funcs_get_eastasian_width_func()
+
+
+* Face API:
+
+ o Renamed API:
+ hb_face_get_table() renamed to hb_face_reference_table()
+ hb_face_create_for_data() renamed to hb_face_create()
+
+ o Changed API:
+ hb_face_create_for_tables() takes user_data before destroy now
+ hb_face_reference_table() returns empty blob instead of NULL
+ hb_get_table_func_t accepts the face as first parameter now
+
+* Font API:
+
+ o Fonts can subclass other fonts now. Unimplemented callbacks in the
+ subclass automatically chainup to the parent. When chaining up,
+ scale is adjusted if the parent font has a different scale.
+
+ o All hb_font_funcs_t callbacks take a user_data now. Their setters
+ take a user_data and its respective destroy callback.
+
+ o New API:
+ hb_font_get_parent()
+ hb_font_funcs_get_empty()
+ hb_font_create_sub_font()
+
+ o Removed API:
+ hb_font_funcs_copy()
+ hb_font_unset_funcs()
+
+ o Removed func getter functions:
+ hb_font_funcs_get_glyph_func()
+ hb_font_funcs_get_glyph_advance_func()
+ hb_font_funcs_get_glyph_extents_func()
+ hb_font_funcs_get_contour_point_func()
+ hb_font_funcs_get_kerning_func()
+
+ o Changed API:
+ hb_font_create() takes a face and references it now
+ hb_font_set_funcs() takes user_data before destroy now
+ hb_font_set_scale() accepts signed integers now
+ hb_font_get_contour_point_func_t now takes glyph first, then point_index
+ hb_font_get_glyph_func_t returns a success boolean now
+
+
+* Changed object model:
+
+ o All object types have a _get_empty() now:
+ hb_blob_get_empty()
+ hb_buffer_get_empty()
+ hb_face_get_empty()
+ hb_font_get_empty()
+ hb_font_funcs_get_empty()
+ hb_unicode_funcs_get_empty()
+
+ o Added _set_user_data() and _get_user_data() for all object types:
+ hb_blob_get_user_data()
+ hb_blob_set_user_data()
+ hb_buffer_get_user_data()
+ hb_buffer_set_user_data()
+ hb_face_get_user_data()
+ hb_face_set_user_data()
+ hb_font_funcs_get_user_data()
+ hb_font_funcs_set_user_data()
+ hb_font_get_user_data()
+ hb_font_set_user_data()
+ hb_unicode_funcs_get_user_data()
+ hb_unicode_funcs_set_user_data()
+
+ o Removed the _get_reference_count() from all object types:
+ hb_blob_get_reference_count()
+ hb_buffer_get_reference_count()
+ hb_face_get_reference_count()
+ hb_font_funcs_get_reference_count()
+ hb_font_get_reference_count()
+ hb_unicode_funcs_get_reference_count()
+
+ o Added _make_immutable() and _is_immutable() for all object types except for buffer:
+ hb_blob_make_immutable()
+ hb_blob_is_immutable()
+ hb_face_make_immutable()
+ hb_face_is_immutable()
+
+
+* Changed API for vertical text support
+
+ o The following callbacks where removed:
+ hb_font_get_glyph_advance_func_t
+ hb_font_get_kerning_func_t
+
+ o The following new callbacks added instead:
+ hb_font_get_glyph_h_advance_func_t
+ hb_font_get_glyph_v_advance_func_t
+ hb_font_get_glyph_h_origin_func_t
+ hb_font_get_glyph_v_origin_func_t
+ hb_font_get_glyph_h_kerning_func_t
+ hb_font_get_glyph_v_kerning_func_t
+
+ o The following API removed as such:
+ hb_font_funcs_set_glyph_advance_func()
+ hb_font_funcs_set_kerning_func()
+ hb_font_get_glyph_advance()
+ hb_font_get_kerning()
+
+ o New API added instead:
+ hb_font_funcs_set_glyph_h_advance_func()
+ hb_font_funcs_set_glyph_v_advance_func()
+ hb_font_funcs_set_glyph_h_origin_func()
+ hb_font_funcs_set_glyph_v_origin_func()
+ hb_font_funcs_set_glyph_h_kerning_func()
+ hb_font_funcs_set_glyph_v_kerning_func()
+ hb_font_get_glyph_h_advance()
+ hb_font_get_glyph_v_advance()
+ hb_font_get_glyph_h_origin()
+ hb_font_get_glyph_v_origin()
+ hb_font_get_glyph_h_kerning()
+ hb_font_get_glyph_v_kerning()
+
+ o The following higher-leve API added for convenience:
+ hb_font_get_glyph_advance_for_direction()
+ hb_font_get_glyph_origin_for_direction()
+ hb_font_add_glyph_origin_for_direction()
+ hb_font_subtract_glyph_origin_for_direction()
+ hb_font_get_glyph_kerning_for_direction()
+ hb_font_get_glyph_extents_for_origin()
+ hb_font_get_glyph_contour_point_for_origin()
+
+
+* OpenType Layout API:
+
+ o New API:
+ hb_ot_layout_position_start()
+ hb_ot_layout_substitute_start()
+ hb_ot_layout_substitute_finish()
+
+
+* Glue code:
+
+ o New API:
+ hb_glib_script_to_script()
+ hb_glib_script_from_script()
+ hb_icu_script_to_script()
+ hb_icu_script_from_script()
+
+
+* Version API added:
+
+ o New API:
+ HB_VERSION_MAJOR
+ HB_VERSION_MINOR
+ HB_VERSION_MICRO
+ HB_VERSION_STRING
+ HB_VERSION_CHECK()
+ hb_version()
+ hb_version_string()
+ hb_version_check()
+
+
diff --git a/src/3rdparty/harfbuzz-ng/README b/src/3rdparty/harfbuzz-ng/README
new file mode 100644
index 0000000000..74e739da52
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/README
@@ -0,0 +1,7 @@
+This is HarfBuzz, a text shaping library.
+
+For bug reports, mailing list, and other information please visit:
+
+ http://harfbuzz.org/
+
+For license information, see the file COPYING.
diff --git a/src/3rdparty/harfbuzz-ng/THANKS b/src/3rdparty/harfbuzz-ng/THANKS
new file mode 100644
index 0000000000..940cfde5c3
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/THANKS
@@ -0,0 +1,7 @@
+Bradley Grainger
+Khaled Hosny
+Kenichi Ishibashi
+Ryan Lortie
+Jeff Muizelaar
+suzuki toshiya
+Philip Withnall
diff --git a/src/3rdparty/harfbuzz-ng/TODO b/src/3rdparty/harfbuzz-ng/TODO
new file mode 100644
index 0000000000..4808391b4e
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/TODO
@@ -0,0 +1,81 @@
+General fixes:
+=============
+
+- AAT 'morx' implementation.
+
+- Return "safe-to-break" bit from shaping.
+
+- Implement 'rand' feature.
+
+- mask propagation? (when ligation, "or" the masks).
+
+- Warn at compile time (and runtime with HB_DEBUG?) if no Unicode / font
+ funcs found / set.
+
+- Misc features:
+ * init/medi/fina/isol for non-cursive scripts
+
+
+API issues to fix before 1.0:
+============================
+
+- API to accept a list of languages?
+
+- Add init_func to font_funcs. Adjust ft.
+
+- hb-ft load_flags issues.
+
+- Add pkg-config files for glue codes (harfbuzz-glib, etc)
+
+- 'const' for getter APIs? (use mutable internally)
+
+- Remove hb_ot_shape_glyphs_closure()?
+
+
+API additions
+=============
+
+- Language to/from script.
+
+- blob_from_file?
+
+- Add hb-cairo glue
+
+- Add sanitize API (and a cached version, that saves result on blob user-data)
+
+- Add glib GBoxedType stuff and introspection
+
+- BCP 47 language handling / API (language_matches?)
+
+- Add hb_font_create_linear()?
+
+- Add query / enumeration API for aalt-like features?
+
+- SFNT api? get_num_faces? get_table_tags? (there's something in stash)
+
+- Add segmentation API
+
+- Add hb-fribidi glue?
+
+
+hb-view / hb-shape enhancements:
+===============================
+
+- Add --width, --height, --auto-size, --align, etc?
+
+
+Tests to write:
+==============
+
+- ot-layout enumeration API (needs font)
+
+- Finish test-shape.c, grep for TODO
+
+- Finish test-unicode.c, grep for TODO
+
+- GObject, FreeType, etc
+
+- hb_cache_t and relatives
+
+- hb_feature_to/from_string
+- hb_buffer_[sg]et_contents
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-blob.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-blob.h
new file mode 100644
index 0000000000..31ccd0fb99
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-blob.h
@@ -0,0 +1 @@
+#include "../../src/hb-blob.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-buffer.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-buffer.h
new file mode 100644
index 0000000000..070330685b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-buffer.h
@@ -0,0 +1 @@
+#include "../../src/hb-buffer.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-common.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-common.h
new file mode 100644
index 0000000000..778dbf37ec
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-common.h
@@ -0,0 +1 @@
+#include "../../src/hb-common.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-deprecated.h
new file mode 100644
index 0000000000..8ac7eab8ea
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-deprecated.h
@@ -0,0 +1 @@
+#include "../../src/hb-deprecated.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-face.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-face.h
new file mode 100644
index 0000000000..a38c4b29ba
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-face.h
@@ -0,0 +1 @@
+#include "../../src/hb-face.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-font.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-font.h
new file mode 100644
index 0000000000..ea395383c4
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-font.h
@@ -0,0 +1 @@
+#include "../../src/hb-font.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-layout.h
new file mode 100644
index 0000000000..2a68a0f235
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-layout.h
@@ -0,0 +1 @@
+#include "../../src/hb-ot-layout.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-tag.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-tag.h
new file mode 100644
index 0000000000..175e5b2921
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-tag.h
@@ -0,0 +1 @@
+#include "../../src/hb-ot-tag.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot.h
new file mode 100644
index 0000000000..b5e233199d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot.h
@@ -0,0 +1 @@
+#include "../../src/hb-ot.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-set.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-set.h
new file mode 100644
index 0000000000..47cc1c3f0d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-set.h
@@ -0,0 +1 @@
+#include "../../src/hb-set.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape-plan.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape-plan.h
new file mode 100644
index 0000000000..6e49cb6b55
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape-plan.h
@@ -0,0 +1 @@
+#include "../../src/hb-shape-plan.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape.h
new file mode 100644
index 0000000000..81881f9cb5
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-shape.h
@@ -0,0 +1 @@
+#include "../../src/hb-shape.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-unicode.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-unicode.h
new file mode 100644
index 0000000000..8712e6605f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-unicode.h
@@ -0,0 +1 @@
+#include "../../src/hb-unicode.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-version.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-version.h
new file mode 100644
index 0000000000..b575c4c98c
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-version.h
@@ -0,0 +1 @@
+#include "../../src/hb-version.h"
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h
new file mode 100644
index 0000000000..d2e89d3443
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h
@@ -0,0 +1 @@
+#include "../../src/hb.h"
diff --git a/src/3rdparty/harfbuzz-ng/src/config.h b/src/3rdparty/harfbuzz-ng/src/config.h
new file mode 100644
index 0000000000..fe9a450533
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/config.h
@@ -0,0 +1,26 @@
+#ifndef HB_CONFIG_H
+#define HB_CONFIG_H
+
+#define HAVE_OT
+
+#define HB_NO_MT
+#define HB_NO_UNICODE_FUNCS
+
+#define HB_DISABLE_DEPRECATED
+
+#include <QtCore/qglobal.h>
+
+#ifndef HB_INTERNAL
+# define HB_INTERNAL Q_DECL_HIDDEN
+#endif
+
+// because strdup() is not part of strict Posix, declare it here
+extern "C" char *strdup(const char *src);
+
+#ifndef HAVE_ATEXIT
+# define HAVE_ATEXIT 1
+# include <QtCore/qcoreapplication.h>
+# define atexit qAddPostRoutine
+#endif
+
+#endif /* HB_CONFIG_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
new file mode 100644
index 0000000000..9cc3bc5587
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
@@ -0,0 +1,132 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Contributor(s):
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_ATOMIC_PRIVATE_HH
+#define HB_ATOMIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* atomic_int */
+
+/* We need external help for these */
+
+#if 0
+
+
+#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#if defined(__MINGW32__) && !defined(MemoryBarrier)
+static inline void _HBMemoryBarrier (void) {
+ long dummy = 0;
+ InterlockedExchange (&dummy, 1);
+}
+# define MemoryBarrier _HBMemoryBarrier
+#endif
+
+typedef LONG hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
+
+#define hb_atomic_ptr_get(P) (MemoryBarrier (), (void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
+
+
+#elif !defined(HB_NO_MT) && defined(__APPLE__)
+
+#include <libkern/OSAtomic.h>
+#ifdef __MAC_OS_X_MIN_REQUIRED
+#include <AvailabilityMacros.h>
+#elif defined(__IPHONE_OS_MIN_REQUIRED)
+#include <Availability.h>
+#endif
+
+typedef int32_t hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
+
+#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P))
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
+#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
+#else
+#if __ppc64__ || __x86_64__
+#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
+#else
+#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
+#endif
+#endif
+
+
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
+
+typedef int hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V))
+
+#define hb_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
+
+
+#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
+
+#include <atomic.h>
+#include <mbarrier.h>
+
+typedef unsigned int hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
+
+#define hb_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
+
+
+#elif !defined(HB_NO_MT)
+
+#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
+typedef volatile int hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V))
+
+#define hb_atomic_ptr_get(P) ((void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
+
+
+#else /* HB_NO_MT */
+
+typedef int hb_atomic_int_t;
+#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V))
+
+#define hb_atomic_ptr_get(P) ((void *) *(P))
+#define hb_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
+
+#endif
+
+/* TODO Add tracing. */
+
+#endif /* HB_ATOMIC_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
new file mode 100644
index 0000000000..dfd134b776
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
@@ -0,0 +1,328 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
+#define _POSIX_C_SOURCE 199309L
+
+#include "hb-private.hh"
+
+#include "hb-blob.h"
+#include "hb-object-private.hh"
+
+#ifdef HAVE_SYS_MMAN_H
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <sys/mman.h>
+#endif /* HAVE_SYS_MMAN_H */
+
+#include <stdio.h>
+#include <errno.h>
+
+
+
+#ifndef HB_DEBUG_BLOB
+#define HB_DEBUG_BLOB (HB_DEBUG+0)
+#endif
+
+
+struct hb_blob_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ bool immutable;
+
+ const char *data;
+ unsigned int length;
+ hb_memory_mode_t mode;
+
+ void *user_data;
+ hb_destroy_func_t destroy;
+};
+
+
+static bool _try_writable (hb_blob_t *blob);
+
+static void
+_hb_blob_destroy_user_data (hb_blob_t *blob)
+{
+ if (blob->destroy) {
+ blob->destroy (blob->user_data);
+ blob->user_data = NULL;
+ blob->destroy = NULL;
+ }
+}
+
+hb_blob_t *
+hb_blob_create (const char *data,
+ unsigned int length,
+ hb_memory_mode_t mode,
+ void *user_data,
+ hb_destroy_func_t destroy)
+{
+ hb_blob_t *blob;
+
+ if (!length || !(blob = hb_object_create<hb_blob_t> ())) {
+ if (destroy)
+ destroy (user_data);
+ return hb_blob_get_empty ();
+ }
+
+ blob->data = data;
+ blob->length = length;
+ blob->mode = mode;
+
+ blob->user_data = user_data;
+ blob->destroy = destroy;
+
+ if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
+ blob->mode = HB_MEMORY_MODE_READONLY;
+ if (!_try_writable (blob)) {
+ hb_blob_destroy (blob);
+ return hb_blob_get_empty ();
+ }
+ }
+
+ return blob;
+}
+
+hb_blob_t *
+hb_blob_create_sub_blob (hb_blob_t *parent,
+ unsigned int offset,
+ unsigned int length)
+{
+ hb_blob_t *blob;
+
+ if (!length || offset >= parent->length)
+ return hb_blob_get_empty ();
+
+ hb_blob_make_immutable (parent);
+
+ blob = hb_blob_create (parent->data + offset,
+ MIN (length, parent->length - offset),
+ HB_MEMORY_MODE_READONLY,
+ hb_blob_reference (parent),
+ (hb_destroy_func_t) hb_blob_destroy);
+
+ return blob;
+}
+
+hb_blob_t *
+hb_blob_get_empty (void)
+{
+ static const hb_blob_t _hb_blob_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* immutable */
+
+ NULL, /* data */
+ 0, /* length */
+ HB_MEMORY_MODE_READONLY, /* mode */
+
+ NULL, /* user_data */
+ NULL /* destroy */
+ };
+
+ return const_cast<hb_blob_t *> (&_hb_blob_nil);
+}
+
+hb_blob_t *
+hb_blob_reference (hb_blob_t *blob)
+{
+ return hb_object_reference (blob);
+}
+
+void
+hb_blob_destroy (hb_blob_t *blob)
+{
+ if (!hb_object_destroy (blob)) return;
+
+ _hb_blob_destroy_user_data (blob);
+
+ free (blob);
+}
+
+hb_bool_t
+hb_blob_set_user_data (hb_blob_t *blob,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (blob, key, data, destroy, replace);
+}
+
+void *
+hb_blob_get_user_data (hb_blob_t *blob,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (blob, key);
+}
+
+
+void
+hb_blob_make_immutable (hb_blob_t *blob)
+{
+ if (hb_object_is_inert (blob))
+ return;
+
+ blob->immutable = true;
+}
+
+hb_bool_t
+hb_blob_is_immutable (hb_blob_t *blob)
+{
+ return blob->immutable;
+}
+
+
+unsigned int
+hb_blob_get_length (hb_blob_t *blob)
+{
+ return blob->length;
+}
+
+const char *
+hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
+{
+ if (length)
+ *length = blob->length;
+
+ return blob->data;
+}
+
+char *
+hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
+{
+ if (!_try_writable (blob)) {
+ if (length)
+ *length = 0;
+
+ return NULL;
+ }
+
+ if (length)
+ *length = blob->length;
+
+ return const_cast<char *> (blob->data);
+}
+
+
+static hb_bool_t
+_try_make_writable_inplace_unix (hb_blob_t *blob)
+{
+#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
+ uintptr_t pagesize = -1, mask, length;
+ const char *addr;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+ pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE);
+#elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pagesize = (uintptr_t) sysconf (_SC_PAGESIZE);
+#elif defined(HAVE_GETPAGESIZE)
+ pagesize = (uintptr_t) getpagesize ();
+#endif
+
+ if ((uintptr_t) -1L == pagesize) {
+ DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
+ return false;
+ }
+ DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
+
+ mask = ~(pagesize-1);
+ addr = (const char *) (((uintptr_t) blob->data) & mask);
+ length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr;
+ DEBUG_MSG_FUNC (BLOB, blob,
+ "calling mprotect on [%p..%p] (%lu bytes)",
+ addr, addr+length, (unsigned long) length);
+ if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
+ DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
+ return false;
+ }
+
+ blob->mode = HB_MEMORY_MODE_WRITABLE;
+
+ DEBUG_MSG_FUNC (BLOB, blob,
+ "successfully made [%p..%p] (%lu bytes) writable\n",
+ addr, addr+length, (unsigned long) length);
+ return true;
+#else
+ return false;
+#endif
+}
+
+static bool
+_try_writable_inplace (hb_blob_t *blob)
+{
+ DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
+
+ if (_try_make_writable_inplace_unix (blob))
+ return true;
+
+ DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
+
+ /* Failed to make writable inplace, mark that */
+ blob->mode = HB_MEMORY_MODE_READONLY;
+ return false;
+}
+
+static bool
+_try_writable (hb_blob_t *blob)
+{
+ if (blob->immutable)
+ return false;
+
+ if (blob->mode == HB_MEMORY_MODE_WRITABLE)
+ return true;
+
+ if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
+ return true;
+
+ if (blob->mode == HB_MEMORY_MODE_WRITABLE)
+ return true;
+
+
+ DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
+
+ char *new_data;
+
+ new_data = (char *) malloc (blob->length);
+ if (unlikely (!new_data))
+ return false;
+
+ DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
+
+ memcpy (new_data, blob->data, blob->length);
+ _hb_blob_destroy_user_data (blob);
+ blob->mode = HB_MEMORY_MODE_WRITABLE;
+ blob->data = new_data;
+ blob->user_data = new_data;
+ blob->destroy = free;
+
+ return true;
+}
+
+
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.h b/src/3rdparty/harfbuzz-ng/src/hb-blob.h
new file mode 100644
index 0000000000..d3d0f41b11
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_BLOB_H
+#define HB_BLOB_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * Note re various memory-modes:
+ *
+ * - In no case shall the HarfBuzz client modify memory
+ * that is passed to HarfBuzz in a blob. If there is
+ * any such possibility, MODE_DUPLICATE should be used
+ * such that HarfBuzz makes a copy immediately,
+ *
+ * - Use MODE_READONLY otherse, unless you really really
+ * really know what you are doing,
+ *
+ * - MODE_WRITABLE is appropriate if you relaly made a
+ * copy of data solely for the purpose of passing to
+ * HarfBuzz and doing that just once (no reuse!),
+ *
+ * - If the font is mmap()ed, it's ok to use
+ * READONLY_MAY_MAKE_WRITABLE, however, there were
+ * design problems with that mode, so HarfBuzz do not
+ * really use it anymore. If not sure, use MODE_READONLY.
+ */
+typedef enum {
+ HB_MEMORY_MODE_DUPLICATE,
+ HB_MEMORY_MODE_READONLY,
+ HB_MEMORY_MODE_WRITABLE,
+ HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
+} hb_memory_mode_t;
+
+typedef struct hb_blob_t hb_blob_t;
+
+hb_blob_t *
+hb_blob_create (const char *data,
+ unsigned int length,
+ hb_memory_mode_t mode,
+ void *user_data,
+ hb_destroy_func_t destroy);
+
+/* Always creates with MEMORY_MODE_READONLY.
+ * Even if the parent blob is writable, we don't
+ * want the user of the sub-blob to be able to
+ * modify the parent data as that data may be
+ * shared among multiple sub-blobs.
+ */
+hb_blob_t *
+hb_blob_create_sub_blob (hb_blob_t *parent,
+ unsigned int offset,
+ unsigned int length);
+
+hb_blob_t *
+hb_blob_get_empty (void);
+
+hb_blob_t *
+hb_blob_reference (hb_blob_t *blob);
+
+void
+hb_blob_destroy (hb_blob_t *blob);
+
+hb_bool_t
+hb_blob_set_user_data (hb_blob_t *blob,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+
+void *
+hb_blob_get_user_data (hb_blob_t *blob,
+ hb_user_data_key_t *key);
+
+
+void
+hb_blob_make_immutable (hb_blob_t *blob);
+
+hb_bool_t
+hb_blob_is_immutable (hb_blob_t *blob);
+
+
+unsigned int
+hb_blob_get_length (hb_blob_t *blob);
+
+const char *
+hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
+
+char *
+hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
+
+
+HB_END_DECLS
+
+#endif /* HB_BLOB_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh
new file mode 100644
index 0000000000..a49dc2ac50
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh
@@ -0,0 +1,643 @@
+
+#line 1 "hb-buffer-deserialize-json.rl"
+/*
+ * Copyright © 2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_DESERIALIZE_JSON_HH
+#define HB_BUFFER_DESERIALIZE_JSON_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-buffer-deserialize-json.hh"
+static const unsigned char _deserialize_json_trans_keys[] = {
+ 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
+ 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
+ 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u,
+ 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u,
+ 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
+ 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0
+};
+
+static const char _deserialize_json_key_spans[] = {
+ 0, 115, 26, 7, 2, 1, 50, 49,
+ 10, 117, 117, 117, 1, 50, 49, 10,
+ 117, 117, 1, 1, 50, 49, 117, 117,
+ 2, 1, 50, 49, 10, 117, 117, 1,
+ 50, 49, 10, 117, 117, 1, 50, 49,
+ 58, 89, 117, 117, 85, 115, 0
+};
+
+static const short _deserialize_json_index_offsets[] = {
+ 0, 0, 116, 143, 151, 154, 156, 207,
+ 257, 268, 386, 504, 622, 624, 675, 725,
+ 736, 854, 972, 974, 976, 1027, 1077, 1195,
+ 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666,
+ 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069,
+ 2119, 2178, 2268, 2386, 2504, 2590, 2706
+};
+
+static const char _deserialize_json_indicies[] = {
+ 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 1, 3, 3, 3,
+ 3, 3, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 1, 4, 1,
+ 5, 1, 6, 7, 1, 1, 8, 1,
+ 9, 10, 1, 11, 1, 11, 11, 11,
+ 11, 11, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 11, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 12, 1,
+ 12, 12, 12, 12, 12, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 12,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 13, 1, 1, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 1, 16, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 1, 18, 18, 18,
+ 18, 18, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 18, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 19, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 20, 1, 21, 21, 21, 21, 21,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 21, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 22,
+ 1, 18, 18, 18, 18, 18, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 18, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 19, 1, 1, 1,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 20, 1, 23,
+ 1, 23, 23, 23, 23, 23, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 23, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 24, 1, 24, 24, 24, 24,
+ 24, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 24, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 25, 1, 1, 26, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 1, 28, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 1, 30, 30, 30, 30, 30, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 30, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 31, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 32, 1, 30,
+ 30, 30, 30, 30, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 30, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 31, 1, 1, 1, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 32, 1, 33, 1, 34,
+ 1, 34, 34, 34, 34, 34, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 34, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 35, 1, 35, 35, 35, 35,
+ 35, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 35, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 36, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 1, 38, 38,
+ 38, 38, 38, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 38, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 39, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 40, 1, 38, 38, 38, 38,
+ 38, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 38, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 39,
+ 1, 1, 1, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 40, 1, 42, 43, 1, 44, 1, 44,
+ 44, 44, 44, 44, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 44, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 45, 1, 45, 45, 45, 45, 45, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 45, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 46, 1,
+ 1, 47, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 1, 49, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 1, 51,
+ 51, 51, 51, 51, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 51, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 52, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 53, 1, 51, 51, 51,
+ 51, 51, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 51, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 52, 1, 1, 1, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 53, 1, 54, 1, 54, 54, 54,
+ 54, 54, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 54, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 55, 1,
+ 55, 55, 55, 55, 55, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 55,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 56, 1, 1, 57,
+ 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 1, 59, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 1, 61, 61, 61,
+ 61, 61, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 61, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 62, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 63, 1, 61, 61, 61, 61, 61,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 61, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 62, 1,
+ 1, 1, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 63,
+ 1, 64, 1, 64, 64, 64, 64, 64,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 64, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 65, 1, 65, 65,
+ 65, 65, 65, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 65, 1, 66,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 67, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 1,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 1, 1, 1, 1, 1, 1,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 1, 70, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 71, 71,
+ 1, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 1, 1, 1, 1, 1,
+ 1, 1, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 1, 1, 1, 1,
+ 71, 1, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 1, 72, 72, 72,
+ 72, 72, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 72, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 73, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 74, 1, 72, 72, 72, 72, 72,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 72, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 73, 1,
+ 1, 1, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 74,
+ 1, 76, 76, 76, 76, 76, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 76, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 77, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 78, 1, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 0
+};
+
+static const char _deserialize_json_trans_targs[] = {
+ 1, 0, 2, 2, 3, 4, 18, 24,
+ 37, 5, 12, 6, 7, 8, 9, 11,
+ 9, 11, 10, 2, 44, 10, 44, 13,
+ 14, 15, 16, 17, 16, 17, 10, 2,
+ 44, 19, 20, 21, 22, 23, 10, 2,
+ 44, 23, 25, 31, 26, 27, 28, 29,
+ 30, 29, 30, 10, 2, 44, 32, 33,
+ 34, 35, 36, 35, 36, 10, 2, 44,
+ 38, 39, 40, 42, 43, 41, 10, 41,
+ 10, 2, 44, 43, 44, 45, 46
+};
+
+static const char _deserialize_json_trans_actions[] = {
+ 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 2,
+ 0, 0, 3, 3, 4, 0, 5, 0,
+ 0, 2, 2, 2, 0, 0, 6, 6,
+ 7, 0, 0, 0, 2, 2, 8, 8,
+ 9, 0, 0, 0, 0, 0, 2, 2,
+ 2, 0, 0, 10, 10, 11, 0, 0,
+ 2, 2, 2, 0, 0, 12, 12, 13,
+ 0, 0, 0, 2, 2, 2, 14, 0,
+ 15, 15, 16, 0, 0, 0, 0
+};
+
+static const int deserialize_json_start = 1;
+static const int deserialize_json_first_final = 44;
+static const int deserialize_json_error = 0;
+
+static const int deserialize_json_en_main = 1;
+
+
+#line 97 "hb-buffer-deserialize-json.rl"
+
+
+static hb_bool_t
+_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
+ const char *buf,
+ unsigned int buf_len,
+ const char **end_ptr,
+ hb_font_t *font)
+{
+ const char *p = buf, *pe = buf + buf_len;
+
+ /* Ensure we have positions. */
+ (void) hb_buffer_get_glyph_positions (buffer, NULL);
+
+ while (p < pe && ISSPACE (*p))
+ p++;
+ if (p < pe && *p == (buffer->len ? ',' : '['))
+ {
+ *end_ptr = ++p;
+ }
+
+ const char *tok = NULL;
+ int cs;
+ hb_glyph_info_t info;
+ hb_glyph_position_t pos;
+
+#line 466 "hb-buffer-deserialize-json.hh"
+ {
+ cs = deserialize_json_start;
+ }
+
+#line 471 "hb-buffer-deserialize-json.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _keys = _deserialize_json_trans_keys + (cs<<1);
+ _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs];
+
+ _slen = _deserialize_json_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+ (*p) <= _keys[1] ?
+ (*p) - _keys[0] : _slen ];
+
+ cs = _deserialize_json_trans_targs[_trans];
+
+ if ( _deserialize_json_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _deserialize_json_trans_actions[_trans] ) {
+ case 1:
+#line 38 "hb-buffer-deserialize-json.rl"
+ {
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+}
+ break;
+ case 5:
+#line 43 "hb-buffer-deserialize-json.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 2:
+#line 51 "hb-buffer-deserialize-json.rl"
+ {
+ tok = p;
+}
+ break;
+ case 14:
+#line 55 "hb-buffer-deserialize-json.rl"
+ {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+ break;
+ case 15:
+#line 62 "hb-buffer-deserialize-json.rl"
+ { if (!parse_uint (tok, p, &info.codepoint)) return false; }
+ break;
+ case 8:
+#line 63 "hb-buffer-deserialize-json.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+ break;
+ case 10:
+#line 64 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.x_offset )) return false; }
+ break;
+ case 12:
+#line 65 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+ break;
+ case 3:
+#line 66 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+ break;
+ case 6:
+#line 67 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+ break;
+ case 16:
+#line 62 "hb-buffer-deserialize-json.rl"
+ { if (!parse_uint (tok, p, &info.codepoint)) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 9:
+#line 63 "hb-buffer-deserialize-json.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 11:
+#line 64 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.x_offset )) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 13:
+#line 65 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 4:
+#line 66 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 7:
+#line 67 "hb-buffer-deserialize-json.rl"
+ { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+#line 624 "hb-buffer-deserialize-json.hh"
+ }
+
+_again:
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ _out: {}
+ }
+
+#line 125 "hb-buffer-deserialize-json.rl"
+
+
+ *end_ptr = p;
+
+ return p == pe && *(p-1) != ']';
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh
new file mode 100644
index 0000000000..7a46ab278b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh
@@ -0,0 +1,571 @@
+
+#line 1 "hb-buffer-deserialize-text.rl"
+/*
+ * Copyright © 2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH
+#define HB_BUFFER_DESERIALIZE_TEXT_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-buffer-deserialize-text.hh"
+static const unsigned char _deserialize_text_trans_keys[] = {
+ 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
+ 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
+ 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
+ 9u, 124u, 9u, 124u, 9u, 124u, 0
+};
+
+static const char _deserialize_text_key_spans[] = {
+ 0, 114, 13, 10, 13, 10, 10, 13,
+ 10, 1, 13, 10, 14, 116, 116, 0,
+ 114, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116
+};
+
+static const short _deserialize_text_index_offsets[] = {
+ 0, 0, 115, 129, 140, 154, 165, 176,
+ 190, 201, 203, 217, 228, 243, 360, 477,
+ 478, 593, 710, 827, 944, 1061, 1178, 1295,
+ 1412, 1529, 1646
+};
+
+static const char _deserialize_text_indicies[] = {
+ 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 1, 1, 1, 1, 1, 1,
+ 1, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 1, 1, 1, 1, 1,
+ 1, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 1, 5, 1, 1, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 1, 8, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 1, 10, 1, 1,
+ 11, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 1, 13, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 1, 15, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 1, 17, 1, 1, 18, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 1, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 1, 22, 1, 23, 1, 1, 24,
+ 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 1, 26, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 1, 22, 1, 1,
+ 1, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 1, 28, 28, 28, 28,
+ 28, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 28, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 29, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 30, 1, 1, 31, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 32, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 33,
+ 1, 34, 34, 34, 34, 34, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 34, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 35, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 36, 1, 1, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 1, 1, 1, 1, 1, 1, 1, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 1, 1, 1, 1, 1, 1, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 1, 28, 28, 28, 28, 28, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 28, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 29, 1, 1, 1,
+ 1, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 1, 1, 1, 30, 1,
+ 1, 31, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 32, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 33, 1, 38,
+ 38, 38, 38, 38, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 38, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 39, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 40, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 41, 1, 42, 42, 42, 42,
+ 42, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 42, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 43, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 44,
+ 1, 42, 42, 42, 42, 42, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 42, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 43, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 44, 1, 38, 38,
+ 38, 38, 38, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 38, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 39, 1, 1, 1, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 40, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 41, 1, 45, 45, 45, 45, 45,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 45, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 46, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 47, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 48,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 49, 1,
+ 50, 50, 50, 50, 50, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 50,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 51, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 52, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 53, 1, 50, 50, 50,
+ 50, 50, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 50, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 51,
+ 1, 1, 1, 1, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 52, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 53, 1, 45, 45, 45, 45, 45, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 45, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 46, 1, 1, 1,
+ 1, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 1, 1, 1, 1, 1,
+ 1, 47, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 48, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 49, 1, 28,
+ 28, 28, 28, 28, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 28, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 29, 1, 55, 55, 1, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 1, 1, 1, 30, 1, 1, 31, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 1, 1, 32, 1, 55, 1, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 1, 33, 1, 0
+};
+
+static const char _deserialize_text_trans_targs[] = {
+ 1, 0, 13, 17, 26, 3, 18, 21,
+ 18, 21, 5, 19, 20, 19, 20, 22,
+ 25, 8, 9, 12, 9, 12, 10, 11,
+ 23, 24, 23, 24, 14, 2, 6, 7,
+ 15, 16, 14, 15, 16, 17, 14, 4,
+ 15, 16, 14, 15, 16, 14, 2, 7,
+ 15, 16, 14, 2, 15, 16, 25, 26
+};
+
+static const char _deserialize_text_trans_actions[] = {
+ 0, 0, 1, 1, 1, 2, 2, 2,
+ 0, 0, 2, 2, 2, 0, 0, 2,
+ 2, 2, 2, 2, 0, 0, 3, 2,
+ 2, 2, 0, 0, 4, 5, 5, 5,
+ 4, 4, 0, 0, 0, 0, 6, 7,
+ 6, 6, 8, 8, 8, 9, 10, 10,
+ 9, 9, 11, 12, 11, 11, 0, 0
+};
+
+static const char _deserialize_text_eof_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0,
+ 0, 4, 6, 8, 8, 6, 9, 11,
+ 11, 9, 4
+};
+
+static const int deserialize_text_start = 1;
+static const int deserialize_text_first_final = 13;
+static const int deserialize_text_error = 0;
+
+static const int deserialize_text_en_main = 1;
+
+
+#line 91 "hb-buffer-deserialize-text.rl"
+
+
+static hb_bool_t
+_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
+ const char *buf,
+ unsigned int buf_len,
+ const char **end_ptr,
+ hb_font_t *font)
+{
+ const char *p = buf, *pe = buf + buf_len;
+
+ /* Ensure we have positions. */
+ (void) hb_buffer_get_glyph_positions (buffer, NULL);
+
+ while (p < pe && ISSPACE (*p))
+ p++;
+ if (p < pe && *p == (buffer->len ? '|' : '['))
+ {
+ *end_ptr = ++p;
+ }
+
+ const char *eof = pe, *tok = NULL;
+ int cs;
+ hb_glyph_info_t info;
+ hb_glyph_position_t pos;
+
+#line 343 "hb-buffer-deserialize-text.hh"
+ {
+ cs = deserialize_text_start;
+ }
+
+#line 348 "hb-buffer-deserialize-text.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _keys = _deserialize_text_trans_keys + (cs<<1);
+ _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs];
+
+ _slen = _deserialize_text_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+ (*p) <= _keys[1] ?
+ (*p) - _keys[0] : _slen ];
+
+ cs = _deserialize_text_trans_targs[_trans];
+
+ if ( _deserialize_text_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _deserialize_text_trans_actions[_trans] ) {
+ case 2:
+#line 51 "hb-buffer-deserialize-text.rl"
+ {
+ tok = p;
+}
+ break;
+ case 5:
+#line 55 "hb-buffer-deserialize-text.rl"
+ {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+ break;
+ case 10:
+#line 62 "hb-buffer-deserialize-text.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+ break;
+ case 3:
+#line 63 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_offset )) return false; }
+ break;
+ case 12:
+#line 64 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+ break;
+ case 7:
+#line 65 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+ break;
+ case 1:
+#line 38 "hb-buffer-deserialize-text.rl"
+ {
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text.rl"
+ {
+ tok = p;
+}
+ break;
+ case 4:
+#line 55 "hb-buffer-deserialize-text.rl"
+ {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 9:
+#line 62 "hb-buffer-deserialize-text.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 11:
+#line 64 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 6:
+#line 65 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 8:
+#line 66 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+#line 480 "hb-buffer-deserialize-text.hh"
+ }
+
+_again:
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( _deserialize_text_eof_actions[cs] ) {
+ case 4:
+#line 55 "hb-buffer-deserialize-text.rl"
+ {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 9:
+#line 62 "hb-buffer-deserialize-text.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 11:
+#line 64 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 6:
+#line 65 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 8:
+#line 66 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+#line 557 "hb-buffer-deserialize-text.hh"
+ }
+ }
+
+ _out: {}
+ }
+
+#line 119 "hb-buffer-deserialize-text.rl"
+
+
+ *end_ptr = p;
+
+ return p == pe && *(p-1) != ']';
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
new file mode 100644
index 0000000000..a8cf770244
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 1998-2004 David Turner and Werner Lemberg
+ * Copyright © 2004,2007,2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_PRIVATE_HH
+#define HB_BUFFER_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-buffer.h"
+#include "hb-object-private.hh"
+#include "hb-unicode-private.hh"
+
+
+ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
+ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
+
+
+/*
+ * hb_buffer_t
+ */
+
+struct hb_buffer_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ /* Information about how the text in the buffer should be treated */
+
+ hb_unicode_funcs_t *unicode; /* Unicode functions */
+ hb_segment_properties_t props; /* Script, language, direction */
+ hb_buffer_flags_t flags; /* BOT / EOT / etc. */
+
+ /* Buffer contents */
+
+ hb_buffer_content_type_t content_type;
+
+ bool in_error; /* Allocation failed */
+ bool have_output; /* Whether we have an output buffer going on */
+ bool have_positions; /* Whether we have positions */
+
+ unsigned int idx; /* Cursor into ->info and ->pos arrays */
+ unsigned int len; /* Length of ->info and ->pos arrays */
+ unsigned int out_len; /* Length of ->out array if have_output */
+
+ unsigned int allocated; /* Length of allocated arrays */
+ hb_glyph_info_t *info;
+ hb_glyph_info_t *out_info;
+ hb_glyph_position_t *pos;
+
+ inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
+ inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
+
+ inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
+ inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
+
+ inline hb_glyph_info_t &prev (void) { return out_info[out_len - 1]; }
+ inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; }
+
+ inline bool has_separate_output (void) const { return info != out_info; }
+
+ unsigned int serial;
+
+ /* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
+ uint8_t allocated_var_bytes[8];
+ const char *allocated_var_owner[8];
+
+ /* Text before / after the main buffer contents.
+ * Always in Unicode, and ordered outward.
+ * Index 0 is for "pre-context", 1 for "post-context". */
+ static const unsigned int CONTEXT_LENGTH = 5;
+ hb_codepoint_t context[2][CONTEXT_LENGTH];
+ unsigned int context_len[2];
+
+
+ /* Methods */
+
+ HB_INTERNAL void reset (void);
+ HB_INTERNAL void clear (void);
+
+ inline unsigned int backtrack_len (void) const
+ { return have_output? out_len : idx; }
+ inline unsigned int next_serial (void) { return serial++; }
+
+ HB_INTERNAL void allocate_var (unsigned int byte_i, unsigned int count, const char *owner);
+ HB_INTERNAL void deallocate_var (unsigned int byte_i, unsigned int count, const char *owner);
+ HB_INTERNAL void assert_var (unsigned int byte_i, unsigned int count, const char *owner);
+ HB_INTERNAL void deallocate_var_all (void);
+
+ HB_INTERNAL void add (hb_codepoint_t codepoint,
+ unsigned int cluster);
+ HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
+
+ HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
+ HB_INTERNAL void reverse (void);
+ HB_INTERNAL void reverse_clusters (void);
+ HB_INTERNAL void guess_segment_properties (void);
+
+ HB_INTERNAL void swap_buffers (void);
+ HB_INTERNAL void remove_output (void);
+ HB_INTERNAL void clear_output (void);
+ HB_INTERNAL void clear_positions (void);
+
+ HB_INTERNAL void replace_glyphs (unsigned int num_in,
+ unsigned int num_out,
+ const hb_codepoint_t *glyph_data);
+
+ HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
+ /* Makes a copy of the glyph at idx to output and replace glyph_index */
+ HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
+ HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
+ /* Copies glyph at idx to output but doesn't advance idx */
+ HB_INTERNAL void copy_glyph (void);
+ /* Copies glyph at idx to output and advance idx.
+ * If there's no output, just advance idx. */
+ inline void
+ next_glyph (void)
+ {
+ if (have_output)
+ {
+ if (unlikely (out_info != info || out_len != idx)) {
+ if (unlikely (!make_room_for (1, 1))) return;
+ out_info[out_len] = info[idx];
+ }
+ out_len++;
+ }
+
+ idx++;
+ }
+
+ /* Advance idx without copying to output. */
+ inline void skip_glyph (void) { idx++; }
+
+ inline void reset_masks (hb_mask_t mask)
+ {
+ for (unsigned int j = 0; j < len; j++)
+ info[j].mask = mask;
+ }
+ inline void add_masks (hb_mask_t mask)
+ {
+ for (unsigned int j = 0; j < len; j++)
+ info[j].mask |= mask;
+ }
+ HB_INTERNAL void set_masks (hb_mask_t value,
+ hb_mask_t mask,
+ unsigned int cluster_start,
+ unsigned int cluster_end);
+
+ HB_INTERNAL void merge_clusters (unsigned int start,
+ unsigned int end);
+ HB_INTERNAL void merge_out_clusters (unsigned int start,
+ unsigned int end);
+
+ /* Internal methods */
+ HB_INTERNAL bool enlarge (unsigned int size);
+
+ inline bool ensure (unsigned int size)
+ { return likely (size < allocated) ? true : enlarge (size); }
+
+ HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
+
+ HB_INTERNAL void *get_scratch_buffer (unsigned int *size);
+
+ inline void clear_context (unsigned int side) { context_len[side] = 0; }
+};
+
+
+#define HB_BUFFER_XALLOCATE_VAR(b, func, var, owner) \
+ b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
+ sizeof (b->info[0].var), owner)
+#define HB_BUFFER_ALLOCATE_VAR(b, var) \
+ HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var (), #var)
+#define HB_BUFFER_DEALLOCATE_VAR(b, var) \
+ HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var (), #var)
+#define HB_BUFFER_ASSERT_VAR(b, var) \
+ HB_BUFFER_XALLOCATE_VAR (b, assert_var, var (), #var)
+
+
+#endif /* HB_BUFFER_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
new file mode 100644
index 0000000000..eac69000dd
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
@@ -0,0 +1,336 @@
+/*
+ * Copyright © 2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-buffer-private.hh"
+
+
+static const char *serialize_formats[] = {
+ "text",
+ "json",
+ NULL
+};
+
+const char **
+hb_buffer_serialize_list_formats (void)
+{
+ return serialize_formats;
+}
+
+hb_buffer_serialize_format_t
+hb_buffer_serialize_format_from_string (const char *str, int len)
+{
+ /* Upper-case it. */
+ return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020);
+}
+
+const char *
+hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
+{
+ switch (format)
+ {
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
+ default:
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL;
+ }
+}
+
+static unsigned int
+_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
+{
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
+
+ *buf_consumed = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ char b[1024];
+ char *p = b;
+
+ /* In the following code, we know b is large enough that no overflow can happen. */
+
+#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END
+
+ if (i)
+ *p++ = ',';
+
+ *p++ = '{';
+
+ APPEND ("\"g\":");
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
+ {
+ char g[128];
+ hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
+ *p++ = '"';
+ for (char *q = g; *q; q++) {
+ if (*q == '"')
+ *p++ = '\\';
+ *p++ = *q;
+ }
+ *p++ = '"';
+ }
+ else
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
+ }
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
+ {
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
+ pos[i].x_offset, pos[i].y_offset);
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
+ pos[i].x_advance, pos[i].y_advance);
+ }
+
+ *p++ = '}';
+
+ if (buf_size > (p - b))
+ {
+ unsigned int l = p - b;
+ memcpy (buf, b, l);
+ buf += l;
+ buf_size -= l;
+ *buf_consumed += l;
+ *buf = '\0';
+ } else
+ return i - start;
+ }
+
+ return end - start;
+}
+
+static unsigned int
+_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
+{
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
+
+ *buf_consumed = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ char b[1024];
+ char *p = b;
+
+ /* In the following code, we know b is large enough that no overflow can happen. */
+
+ if (i)
+ *p++ = '|';
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
+ {
+ hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
+ p += strlen (p);
+ }
+ else
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
+ }
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
+ {
+ if (pos[i].x_offset || pos[i].y_offset)
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset));
+
+ *p++ = '+';
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
+ if (pos->y_advance)
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
+ }
+
+ if (buf_size > (p - b))
+ {
+ unsigned int l = p - b;
+ memcpy (buf, b, l);
+ buf += l;
+ buf_size -= l;
+ *buf_consumed += l;
+ *buf = '\0';
+ } else
+ return i - start;
+ }
+
+ return end - start;
+}
+
+/* Returns number of items, starting at start, that were serialized. */
+unsigned int
+hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed, /* May be NULL */
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags)
+{
+ assert (start <= end && end <= buffer->len);
+
+ unsigned int sconsumed;
+ if (!buf_consumed)
+ buf_consumed = &sconsumed;
+ *buf_consumed = 0;
+
+ assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
+ buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+ if (unlikely (start == end))
+ return 0;
+
+ if (!font)
+ font = hb_font_get_empty ();
+
+ switch (format)
+ {
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
+ return _hb_buffer_serialize_glyphs_text (buffer, start, end,
+ buf, buf_size, buf_consumed,
+ font, flags);
+
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON:
+ return _hb_buffer_serialize_glyphs_json (buffer, start, end,
+ buf, buf_size, buf_consumed,
+ font, flags);
+
+ default:
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
+ return 0;
+
+ }
+}
+
+
+static hb_bool_t
+parse_uint (const char *pp, const char *end, uint32_t *pv)
+{
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+ strncpy (buf, pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ uint32_t v;
+
+ errno = 0;
+ v = strtol (p, &pend, 10);
+ if (errno || p == pend || pend - p != end - pp)
+ return false;
+
+ *pv = v;
+ return true;
+}
+
+static hb_bool_t
+parse_int (const char *pp, const char *end, int32_t *pv)
+{
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+ strncpy (buf, pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ int32_t v;
+
+ errno = 0;
+ v = strtol (p, &pend, 10);
+ if (errno || p == pend || pend - p != end - pp)
+ return false;
+
+ *pv = v;
+ return true;
+}
+
+#include "hb-buffer-deserialize-json.hh"
+#include "hb-buffer-deserialize-text.hh"
+
+hb_bool_t
+hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
+ const char *buf,
+ int buf_len, /* -1 means nul-terminated */
+ const char **end_ptr, /* May be NULL */
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format)
+{
+ const char *end;
+ if (!end_ptr)
+ end_ptr = &end;
+ *end_ptr = buf;
+
+ assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
+ buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+ if (buf_len == -1)
+ buf_len = strlen (buf);
+
+ if (!buf_len)
+ {
+ *end_ptr = buf;
+ return false;
+ }
+
+ hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+ if (!font)
+ font = hb_font_get_empty ();
+
+ switch (format)
+ {
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
+ return _hb_buffer_deserialize_glyphs_text (buffer,
+ buf, buf_len, end_ptr,
+ font);
+
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON:
+ return _hb_buffer_deserialize_glyphs_json (buffer,
+ buf, buf_len, end_ptr,
+ font);
+
+ default:
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
+ return false;
+
+ }
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
new file mode 100644
index 0000000000..340bd5351b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
@@ -0,0 +1,1077 @@
+/*
+ * Copyright © 1998-2004 David Turner and Werner Lemberg
+ * Copyright © 2004,2007,2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-buffer-private.hh"
+#include "hb-utf-private.hh"
+
+
+#ifndef HB_DEBUG_BUFFER
+#define HB_DEBUG_BUFFER (HB_DEBUG+0)
+#endif
+
+
+hb_bool_t
+hb_segment_properties_equal (const hb_segment_properties_t *a,
+ const hb_segment_properties_t *b)
+{
+ return a->direction == b->direction &&
+ a->script == b->script &&
+ a->language == b->language &&
+ a->reserved1 == b->reserved1 &&
+ a->reserved2 == b->reserved2;
+
+}
+
+unsigned int
+hb_segment_properties_hash (const hb_segment_properties_t *p)
+{
+ return (unsigned int) p->direction ^
+ (unsigned int) p->script ^
+ (intptr_t) (p->language);
+}
+
+
+
+/* Here is how the buffer works internally:
+ *
+ * There are two info pointers: info and out_info. They always have
+ * the same allocated size, but different lengths.
+ *
+ * As an optimization, both info and out_info may point to the
+ * same piece of memory, which is owned by info. This remains the
+ * case as long as out_len doesn't exceed i at any time.
+ * In that case, swap_buffers() is no-op and the glyph operations operate
+ * mostly in-place.
+ *
+ * As soon as out_info gets longer than info, out_info is moved over
+ * to an alternate buffer (which we reuse the pos buffer for!), and its
+ * current contents (out_len entries) are copied to the new place.
+ * This should all remain transparent to the user. swap_buffers() then
+ * switches info and out_info.
+ */
+
+
+
+/* Internal API */
+
+bool
+hb_buffer_t::enlarge (unsigned int size)
+{
+ if (unlikely (in_error))
+ return false;
+
+ unsigned int new_allocated = allocated;
+ hb_glyph_position_t *new_pos = NULL;
+ hb_glyph_info_t *new_info = NULL;
+ bool separate_out = out_info != info;
+
+ if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
+ goto done;
+
+ while (size >= new_allocated)
+ new_allocated += (new_allocated >> 1) + 32;
+
+ ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0]));
+ if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
+ goto done;
+
+ new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
+ new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
+
+done:
+ if (unlikely (!new_pos || !new_info))
+ in_error = true;
+
+ if (likely (new_pos))
+ pos = new_pos;
+
+ if (likely (new_info))
+ info = new_info;
+
+ out_info = separate_out ? (hb_glyph_info_t *) pos : info;
+ if (likely (!in_error))
+ allocated = new_allocated;
+
+ return likely (!in_error);
+}
+
+bool
+hb_buffer_t::make_room_for (unsigned int num_in,
+ unsigned int num_out)
+{
+ if (unlikely (!ensure (out_len + num_out))) return false;
+
+ if (out_info == info &&
+ out_len + num_out > idx + num_in)
+ {
+ assert (have_output);
+
+ out_info = (hb_glyph_info_t *) pos;
+ memcpy (out_info, info, out_len * sizeof (out_info[0]));
+ }
+
+ return true;
+}
+
+void *
+hb_buffer_t::get_scratch_buffer (unsigned int *size)
+{
+ have_output = false;
+ have_positions = false;
+
+ out_len = 0;
+ out_info = info;
+
+ *size = allocated * sizeof (pos[0]);
+ return pos;
+}
+
+
+
+/* HarfBuzz-Internal API */
+
+void
+hb_buffer_t::reset (void)
+{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
+ hb_unicode_funcs_destroy (unicode);
+ unicode = hb_unicode_funcs_get_default ();
+
+ clear ();
+}
+
+void
+hb_buffer_t::clear (void)
+{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
+ hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
+ props = default_props;
+ flags = HB_BUFFER_FLAG_DEFAULT;
+
+ content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
+ in_error = false;
+ have_output = false;
+ have_positions = false;
+
+ idx = 0;
+ len = 0;
+ out_len = 0;
+ out_info = info;
+
+ serial = 0;
+ memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
+ memset (allocated_var_owner, 0, sizeof allocated_var_owner);
+
+ memset (context, 0, sizeof context);
+ memset (context_len, 0, sizeof context_len);
+}
+
+void
+hb_buffer_t::add (hb_codepoint_t codepoint,
+ unsigned int cluster)
+{
+ hb_glyph_info_t *glyph;
+
+ if (unlikely (!ensure (len + 1))) return;
+
+ glyph = &info[len];
+
+ memset (glyph, 0, sizeof (*glyph));
+ glyph->codepoint = codepoint;
+ glyph->mask = 1;
+ glyph->cluster = cluster;
+
+ len++;
+}
+
+void
+hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info)
+{
+ if (unlikely (!ensure (len + 1))) return;
+
+ info[len] = glyph_info;
+
+ len++;
+}
+
+
+void
+hb_buffer_t::remove_output (void)
+{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
+ have_output = false;
+ have_positions = false;
+
+ out_len = 0;
+ out_info = info;
+}
+
+void
+hb_buffer_t::clear_output (void)
+{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
+ have_output = true;
+ have_positions = false;
+
+ out_len = 0;
+ out_info = info;
+}
+
+void
+hb_buffer_t::clear_positions (void)
+{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
+ have_output = false;
+ have_positions = true;
+
+ out_len = 0;
+ out_info = info;
+
+ memset (pos, 0, sizeof (pos[0]) * len);
+}
+
+void
+hb_buffer_t::swap_buffers (void)
+{
+ if (unlikely (in_error)) return;
+
+ assert (have_output);
+ have_output = false;
+
+ if (out_info != info)
+ {
+ hb_glyph_info_t *tmp_string;
+ tmp_string = info;
+ info = out_info;
+ out_info = tmp_string;
+ pos = (hb_glyph_position_t *) out_info;
+ }
+
+ unsigned int tmp;
+ tmp = len;
+ len = out_len;
+ out_len = tmp;
+
+ idx = 0;
+}
+
+
+void
+hb_buffer_t::replace_glyphs (unsigned int num_in,
+ unsigned int num_out,
+ const uint32_t *glyph_data)
+{
+ if (unlikely (!make_room_for (num_in, num_out))) return;
+
+ merge_clusters (idx, idx + num_in);
+
+ hb_glyph_info_t orig_info = info[idx];
+ hb_glyph_info_t *pinfo = &out_info[out_len];
+ for (unsigned int i = 0; i < num_out; i++)
+ {
+ *pinfo = orig_info;
+ pinfo->codepoint = glyph_data[i];
+ pinfo++;
+ }
+
+ idx += num_in;
+ out_len += num_out;
+}
+
+void
+hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
+{
+ if (unlikely (!make_room_for (0, 1))) return;
+
+ out_info[out_len] = info[idx];
+ out_info[out_len].codepoint = glyph_index;
+
+ out_len++;
+}
+
+void
+hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info)
+{
+ if (unlikely (!make_room_for (0, 1))) return;
+
+ out_info[out_len] = glyph_info;
+
+ out_len++;
+}
+
+void
+hb_buffer_t::copy_glyph (void)
+{
+ if (unlikely (!make_room_for (0, 1))) return;
+
+ out_info[out_len] = info[idx];
+
+ out_len++;
+}
+
+void
+hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
+{
+ if (unlikely (out_info != info || out_len != idx)) {
+ if (unlikely (!make_room_for (1, 1))) return;
+ out_info[out_len] = info[idx];
+ }
+ out_info[out_len].codepoint = glyph_index;
+
+ idx++;
+ out_len++;
+}
+
+
+void
+hb_buffer_t::set_masks (hb_mask_t value,
+ hb_mask_t mask,
+ unsigned int cluster_start,
+ unsigned int cluster_end)
+{
+ hb_mask_t not_mask = ~mask;
+ value &= mask;
+
+ if (!mask)
+ return;
+
+ if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].mask = (info[i].mask & not_mask) | value;
+ return;
+ }
+
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
+ info[i].mask = (info[i].mask & not_mask) | value;
+}
+
+void
+hb_buffer_t::reverse_range (unsigned int start,
+ unsigned int end)
+{
+ unsigned int i, j;
+
+ if (start == end - 1)
+ return;
+
+ for (i = start, j = end - 1; i < j; i++, j--) {
+ hb_glyph_info_t t;
+
+ t = info[i];
+ info[i] = info[j];
+ info[j] = t;
+ }
+
+ if (pos) {
+ for (i = start, j = end - 1; i < j; i++, j--) {
+ hb_glyph_position_t t;
+
+ t = pos[i];
+ pos[i] = pos[j];
+ pos[j] = t;
+ }
+ }
+}
+
+void
+hb_buffer_t::reverse (void)
+{
+ if (unlikely (!len))
+ return;
+
+ reverse_range (0, len);
+}
+
+void
+hb_buffer_t::reverse_clusters (void)
+{
+ unsigned int i, start, count, last_cluster;
+
+ if (unlikely (!len))
+ return;
+
+ reverse ();
+
+ count = len;
+ start = 0;
+ last_cluster = info[0].cluster;
+ for (i = 1; i < count; i++) {
+ if (last_cluster != info[i].cluster) {
+ reverse_range (start, i);
+ start = i;
+ last_cluster = info[i].cluster;
+ }
+ }
+ reverse_range (start, i);
+}
+
+void
+hb_buffer_t::merge_clusters (unsigned int start,
+ unsigned int end)
+{
+ if (unlikely (end - start < 2))
+ return;
+
+ unsigned int cluster = info[start].cluster;
+
+ for (unsigned int i = start + 1; i < end; i++)
+ cluster = MIN (cluster, info[i].cluster);
+
+ /* Extend end */
+ while (end < len && info[end - 1].cluster == info[end].cluster)
+ end++;
+
+ /* Extend start */
+ while (idx < start && info[start - 1].cluster == info[start].cluster)
+ start--;
+
+ /* If we hit the start of buffer, continue in out-buffer. */
+ if (idx == start)
+ for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
+ out_info[i - 1].cluster = cluster;
+
+ for (unsigned int i = start; i < end; i++)
+ info[i].cluster = cluster;
+}
+void
+hb_buffer_t::merge_out_clusters (unsigned int start,
+ unsigned int end)
+{
+ if (unlikely (end - start < 2))
+ return;
+
+ unsigned int cluster = out_info[start].cluster;
+
+ for (unsigned int i = start + 1; i < end; i++)
+ cluster = MIN (cluster, out_info[i].cluster);
+
+ /* Extend start */
+ while (start && out_info[start - 1].cluster == out_info[start].cluster)
+ start--;
+
+ /* Extend end */
+ while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
+ end++;
+
+ /* If we hit the end of out-buffer, continue in buffer. */
+ if (end == out_len)
+ for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
+ info[i].cluster = cluster;
+
+ for (unsigned int i = start; i < end; i++)
+ out_info[i].cluster = cluster;
+}
+
+void
+hb_buffer_t::guess_segment_properties (void)
+{
+ assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+
+ /* If script is set to INVALID, guess from buffer contents */
+ if (props.script == HB_SCRIPT_INVALID) {
+ for (unsigned int i = 0; i < len; i++) {
+ hb_script_t script = unicode->script (info[i].codepoint);
+ if (likely (script != HB_SCRIPT_COMMON &&
+ script != HB_SCRIPT_INHERITED &&
+ script != HB_SCRIPT_UNKNOWN)) {
+ props.script = script;
+ break;
+ }
+ }
+ }
+
+ /* If direction is set to INVALID, guess from script */
+ if (props.direction == HB_DIRECTION_INVALID) {
+ props.direction = hb_script_get_horizontal_direction (props.script);
+ }
+
+ /* If language is not set, use default language from locale */
+ if (props.language == HB_LANGUAGE_INVALID) {
+ /* TODO get_default_for_script? using $LANGUAGE */
+ props.language = hb_language_get_default ();
+ }
+}
+
+
+static inline void
+dump_var_allocation (const hb_buffer_t *buffer)
+{
+ char buf[80];
+ for (unsigned int i = 0; i < 8; i++)
+ buf[i] = '0' + buffer->allocated_var_bytes[7 - i];
+ buf[8] = '\0';
+ DEBUG_MSG (BUFFER, buffer,
+ "Current var allocation: %s",
+ buf);
+}
+
+void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+ assert (byte_i < 8 && byte_i + count <= 8);
+
+ if (DEBUG_ENABLED (BUFFER))
+ dump_var_allocation (this);
+ DEBUG_MSG (BUFFER, this,
+ "Allocating var bytes %d..%d for %s",
+ byte_i, byte_i + count - 1, owner);
+
+ for (unsigned int i = byte_i; i < byte_i + count; i++) {
+ assert (!allocated_var_bytes[i]);
+ allocated_var_bytes[i]++;
+ allocated_var_owner[i] = owner;
+ }
+}
+
+void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+ if (DEBUG_ENABLED (BUFFER))
+ dump_var_allocation (this);
+
+ DEBUG_MSG (BUFFER, this,
+ "Deallocating var bytes %d..%d for %s",
+ byte_i, byte_i + count - 1, owner);
+
+ assert (byte_i < 8 && byte_i + count <= 8);
+ for (unsigned int i = byte_i; i < byte_i + count; i++) {
+ assert (allocated_var_bytes[i]);
+ assert (0 == strcmp (allocated_var_owner[i], owner));
+ allocated_var_bytes[i]--;
+ }
+}
+
+void hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+ if (DEBUG_ENABLED (BUFFER))
+ dump_var_allocation (this);
+
+ DEBUG_MSG (BUFFER, this,
+ "Asserting var bytes %d..%d for %s",
+ byte_i, byte_i + count - 1, owner);
+
+ assert (byte_i < 8 && byte_i + count <= 8);
+ for (unsigned int i = byte_i; i < byte_i + count; i++) {
+ assert (allocated_var_bytes[i]);
+ assert (0 == strcmp (allocated_var_owner[i], owner));
+ }
+}
+
+void hb_buffer_t::deallocate_var_all (void)
+{
+ memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes));
+ memset (allocated_var_owner, 0, sizeof (allocated_var_owner));
+}
+
+/* Public API */
+
+hb_buffer_t *
+hb_buffer_create (void)
+{
+ hb_buffer_t *buffer;
+
+ if (!(buffer = hb_object_create<hb_buffer_t> ()))
+ return hb_buffer_get_empty ();
+
+ buffer->reset ();
+
+ return buffer;
+}
+
+hb_buffer_t *
+hb_buffer_get_empty (void)
+{
+ static const hb_buffer_t _hb_buffer_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
+ HB_SEGMENT_PROPERTIES_DEFAULT,
+ HB_BUFFER_FLAG_DEFAULT,
+
+ HB_BUFFER_CONTENT_TYPE_INVALID,
+ true, /* in_error */
+ true, /* have_output */
+ true /* have_positions */
+
+ /* Zero is good enough for everything else. */
+ };
+
+ return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
+}
+
+hb_buffer_t *
+hb_buffer_reference (hb_buffer_t *buffer)
+{
+ return hb_object_reference (buffer);
+}
+
+void
+hb_buffer_destroy (hb_buffer_t *buffer)
+{
+ if (!hb_object_destroy (buffer)) return;
+
+ hb_unicode_funcs_destroy (buffer->unicode);
+
+ free (buffer->info);
+ free (buffer->pos);
+
+ free (buffer);
+}
+
+hb_bool_t
+hb_buffer_set_user_data (hb_buffer_t *buffer,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (buffer, key, data, destroy, replace);
+}
+
+void *
+hb_buffer_get_user_data (hb_buffer_t *buffer,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (buffer, key);
+}
+
+
+void
+hb_buffer_set_content_type (hb_buffer_t *buffer,
+ hb_buffer_content_type_t content_type)
+{
+ buffer->content_type = content_type;
+}
+
+hb_buffer_content_type_t
+hb_buffer_get_content_type (hb_buffer_t *buffer)
+{
+ return buffer->content_type;
+}
+
+
+void
+hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
+ hb_unicode_funcs_t *unicode)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ if (!unicode)
+ unicode = hb_unicode_funcs_get_default ();
+
+
+ hb_unicode_funcs_reference (unicode);
+ hb_unicode_funcs_destroy (buffer->unicode);
+ buffer->unicode = unicode;
+}
+
+hb_unicode_funcs_t *
+hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
+{
+ return buffer->unicode;
+}
+
+void
+hb_buffer_set_direction (hb_buffer_t *buffer,
+ hb_direction_t direction)
+
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->props.direction = direction;
+}
+
+hb_direction_t
+hb_buffer_get_direction (hb_buffer_t *buffer)
+{
+ return buffer->props.direction;
+}
+
+void
+hb_buffer_set_script (hb_buffer_t *buffer,
+ hb_script_t script)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->props.script = script;
+}
+
+hb_script_t
+hb_buffer_get_script (hb_buffer_t *buffer)
+{
+ return buffer->props.script;
+}
+
+void
+hb_buffer_set_language (hb_buffer_t *buffer,
+ hb_language_t language)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->props.language = language;
+}
+
+hb_language_t
+hb_buffer_get_language (hb_buffer_t *buffer)
+{
+ return buffer->props.language;
+}
+
+void
+hb_buffer_set_segment_properties (hb_buffer_t *buffer,
+ const hb_segment_properties_t *props)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->props = *props;
+}
+
+void
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+ hb_segment_properties_t *props)
+{
+ *props = buffer->props;
+}
+
+
+void
+hb_buffer_set_flags (hb_buffer_t *buffer,
+ hb_buffer_flags_t flags)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->flags = flags;
+}
+
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer)
+{
+ return buffer->flags;
+}
+
+
+void
+hb_buffer_reset (hb_buffer_t *buffer)
+{
+ buffer->reset ();
+}
+
+void
+hb_buffer_clear_contents (hb_buffer_t *buffer)
+{
+ buffer->clear ();
+}
+
+hb_bool_t
+hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
+{
+ return buffer->ensure (size);
+}
+
+hb_bool_t
+hb_buffer_allocation_successful (hb_buffer_t *buffer)
+{
+ return !buffer->in_error;
+}
+
+void
+hb_buffer_add (hb_buffer_t *buffer,
+ hb_codepoint_t codepoint,
+ unsigned int cluster)
+{
+ buffer->add (codepoint, cluster);
+ buffer->clear_context (1);
+}
+
+hb_bool_t
+hb_buffer_set_length (hb_buffer_t *buffer,
+ unsigned int length)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return length == 0;
+
+ if (!buffer->ensure (length))
+ return false;
+
+ /* Wipe the new space */
+ if (length > buffer->len) {
+ memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
+ if (buffer->have_positions)
+ memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
+ }
+
+ buffer->len = length;
+
+ if (!length)
+ buffer->clear_context (0);
+ buffer->clear_context (1);
+
+ return true;
+}
+
+unsigned int
+hb_buffer_get_length (hb_buffer_t *buffer)
+{
+ return buffer->len;
+}
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_info_t *
+hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
+ unsigned int *length)
+{
+ if (length)
+ *length = buffer->len;
+
+ return (hb_glyph_info_t *) buffer->info;
+}
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_position_t *
+hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
+ unsigned int *length)
+{
+ if (!buffer->have_positions)
+ buffer->clear_positions ();
+
+ if (length)
+ *length = buffer->len;
+
+ return (hb_glyph_position_t *) buffer->pos;
+}
+
+void
+hb_buffer_reverse (hb_buffer_t *buffer)
+{
+ buffer->reverse ();
+}
+
+void
+hb_buffer_reverse_clusters (hb_buffer_t *buffer)
+{
+ buffer->reverse_clusters ();
+}
+
+void
+hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
+{
+ buffer->guess_segment_properties ();
+}
+
+template <typename T>
+static inline void
+hb_buffer_add_utf (hb_buffer_t *buffer,
+ const T *text,
+ int text_length,
+ unsigned int item_offset,
+ int item_length)
+{
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ if (text_length == -1)
+ text_length = hb_utf_strlen (text);
+
+ if (item_length == -1)
+ item_length = text_length - item_offset;
+
+ buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
+
+ /* If buffer is empty and pre-context provided, install it.
+ * This check is written this way, to make sure people can
+ * provide pre-context in one add_utf() call, then provide
+ * text in a follow-up call. See:
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13
+ */
+ if (!buffer->len && item_offset > 0)
+ {
+ /* Add pre-context */
+ buffer->clear_context (0);
+ const T *prev = text + item_offset;
+ const T *start = text;
+ while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
+ {
+ hb_codepoint_t u;
+ prev = hb_utf_prev (prev, start, &u);
+ buffer->context[0][buffer->context_len[0]++] = u;
+ }
+ }
+
+ const T *next = text + item_offset;
+ const T *end = next + item_length;
+ while (next < end)
+ {
+ hb_codepoint_t u;
+ const T *old_next = next;
+ next = hb_utf_next (next, end, &u);
+ buffer->add (u, old_next - (const T *) text);
+ }
+
+ /* Add post-context */
+ buffer->clear_context (1);
+ end = text + text_length;
+ while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
+ {
+ hb_codepoint_t u;
+ next = hb_utf_next (next, end, &u);
+ buffer->context[1][buffer->context_len[1]++] = u;
+ }
+
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+}
+
+void
+hb_buffer_add_utf8 (hb_buffer_t *buffer,
+ const char *text,
+ int text_length,
+ unsigned int item_offset,
+ int item_length)
+{
+ hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
+}
+
+void
+hb_buffer_add_utf16 (hb_buffer_t *buffer,
+ const uint16_t *text,
+ int text_length,
+ unsigned int item_offset,
+ int item_length)
+{
+ hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
+}
+
+void
+hb_buffer_add_utf32 (hb_buffer_t *buffer,
+ const uint32_t *text,
+ int text_length,
+ unsigned int item_offset,
+ int item_length)
+{
+ hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
+}
+
+
+static int
+compare_info_codepoint (const hb_glyph_info_t *pa,
+ const hb_glyph_info_t *pb)
+{
+ return (int) pb->codepoint - (int) pa->codepoint;
+}
+
+static inline void
+normalize_glyphs_cluster (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ bool backward)
+{
+ hb_glyph_position_t *pos = buffer->pos;
+
+ /* Total cluster advance */
+ hb_position_t total_x_advance = 0, total_y_advance = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ total_x_advance += pos[i].x_advance;
+ total_y_advance += pos[i].y_advance;
+ }
+
+ hb_position_t x_advance = 0, y_advance = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ pos[i].x_offset += x_advance;
+ pos[i].y_offset += y_advance;
+
+ x_advance += pos[i].x_advance;
+ y_advance += pos[i].y_advance;
+
+ pos[i].x_advance = 0;
+ pos[i].y_advance = 0;
+ }
+
+ if (backward)
+ {
+ /* Transfer all cluster advance to the last glyph. */
+ pos[end - 1].x_advance = total_x_advance;
+ pos[end - 1].y_advance = total_y_advance;
+
+ hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
+ } else {
+ /* Transfer all cluster advance to the first glyph. */
+ pos[start].x_advance += total_x_advance;
+ pos[start].y_advance += total_y_advance;
+ for (unsigned int i = start + 1; i < end; i++) {
+ pos[i].x_offset -= total_x_advance;
+ pos[i].y_offset -= total_y_advance;
+ }
+ hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
+ }
+}
+
+void
+hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
+{
+ assert (buffer->have_positions);
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+ bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+ hb_glyph_info_t *info = buffer->info;
+
+ unsigned int start = 0;
+ unsigned int end;
+ for (end = start + 1; end < count; end++)
+ if (info[start].cluster != info[end].cluster) {
+ normalize_glyphs_cluster (buffer, start, end, backward);
+ start = end;
+ }
+ normalize_glyphs_cluster (buffer, start, end, backward);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
new file mode 100644
index 0000000000..87c4ce58e8
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright © 1998-2004 David Turner and Werner Lemberg
+ * Copyright © 2004,2007,2009 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_BUFFER_H
+#define HB_BUFFER_H
+
+#include "hb-common.h"
+#include "hb-unicode.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct hb_glyph_info_t {
+ hb_codepoint_t codepoint;
+ hb_mask_t mask;
+ uint32_t cluster;
+
+ /*< private >*/
+ hb_var_int_t var1;
+ hb_var_int_t var2;
+} hb_glyph_info_t;
+
+typedef struct hb_glyph_position_t {
+ hb_position_t x_advance;
+ hb_position_t y_advance;
+ hb_position_t x_offset;
+ hb_position_t y_offset;
+
+ /*< private >*/
+ hb_var_int_t var;
+} hb_glyph_position_t;
+
+
+typedef struct hb_segment_properties_t {
+ hb_direction_t direction;
+ hb_script_t script;
+ hb_language_t language;
+ /*< private >*/
+ void *reserved1;
+ void *reserved2;
+} hb_segment_properties_t;
+
+#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
+ HB_SCRIPT_INVALID, \
+ HB_LANGUAGE_INVALID, \
+ NULL, \
+ NULL}
+
+hb_bool_t
+hb_segment_properties_equal (const hb_segment_properties_t *a,
+ const hb_segment_properties_t *b);
+
+unsigned int
+hb_segment_properties_hash (const hb_segment_properties_t *p);
+
+
+
+/*
+ * hb_buffer_t
+ */
+
+typedef struct hb_buffer_t hb_buffer_t;
+
+hb_buffer_t *
+hb_buffer_create (void);
+
+hb_buffer_t *
+hb_buffer_get_empty (void);
+
+hb_buffer_t *
+hb_buffer_reference (hb_buffer_t *buffer);
+
+void
+hb_buffer_destroy (hb_buffer_t *buffer);
+
+hb_bool_t
+hb_buffer_set_user_data (hb_buffer_t *buffer,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+void *
+hb_buffer_get_user_data (hb_buffer_t *buffer,
+ hb_user_data_key_t *key);
+
+
+typedef enum {
+ HB_BUFFER_CONTENT_TYPE_INVALID = 0,
+ HB_BUFFER_CONTENT_TYPE_UNICODE,
+ HB_BUFFER_CONTENT_TYPE_GLYPHS
+} hb_buffer_content_type_t;
+
+void
+hb_buffer_set_content_type (hb_buffer_t *buffer,
+ hb_buffer_content_type_t content_type);
+
+hb_buffer_content_type_t
+hb_buffer_get_content_type (hb_buffer_t *buffer);
+
+
+void
+hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
+ hb_unicode_funcs_t *unicode_funcs);
+
+hb_unicode_funcs_t *
+hb_buffer_get_unicode_funcs (hb_buffer_t *buffer);
+
+void
+hb_buffer_set_direction (hb_buffer_t *buffer,
+ hb_direction_t direction);
+
+hb_direction_t
+hb_buffer_get_direction (hb_buffer_t *buffer);
+
+void
+hb_buffer_set_script (hb_buffer_t *buffer,
+ hb_script_t script);
+
+hb_script_t
+hb_buffer_get_script (hb_buffer_t *buffer);
+
+void
+hb_buffer_set_language (hb_buffer_t *buffer,
+ hb_language_t language);
+
+
+hb_language_t
+hb_buffer_get_language (hb_buffer_t *buffer);
+
+void
+hb_buffer_set_segment_properties (hb_buffer_t *buffer,
+ const hb_segment_properties_t *props);
+
+void
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+ hb_segment_properties_t *props);
+
+void
+hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
+
+
+typedef enum { /*< flags >*/
+ HB_BUFFER_FLAG_DEFAULT = 0x00000000,
+ HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */
+ HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */
+ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004
+} hb_buffer_flags_t;
+
+void
+hb_buffer_set_flags (hb_buffer_t *buffer,
+ hb_buffer_flags_t flags);
+
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer);
+
+
+/* Resets the buffer. Afterwards it's as if it was just created,
+ * except that it has a larger buffer allocated perhaps... */
+void
+hb_buffer_reset (hb_buffer_t *buffer);
+
+/* Like reset, but does NOT clear unicode_funcs. */
+void
+hb_buffer_clear_contents (hb_buffer_t *buffer);
+
+/* Returns false if allocation failed */
+hb_bool_t
+hb_buffer_pre_allocate (hb_buffer_t *buffer,
+ unsigned int size);
+
+
+/* Returns false if allocation has failed before */
+hb_bool_t
+hb_buffer_allocation_successful (hb_buffer_t *buffer);
+
+void
+hb_buffer_reverse (hb_buffer_t *buffer);
+
+void
+hb_buffer_reverse_clusters (hb_buffer_t *buffer);
+
+
+/* Filling the buffer in */
+
+void
+hb_buffer_add (hb_buffer_t *buffer,
+ hb_codepoint_t codepoint,
+ unsigned int cluster);
+
+void
+hb_buffer_add_utf8 (hb_buffer_t *buffer,
+ const char *text,
+ int text_length,
+ unsigned int item_offset,
+ int item_length);
+
+void
+hb_buffer_add_utf16 (hb_buffer_t *buffer,
+ const uint16_t *text,
+ int text_length,
+ unsigned int item_offset,
+ int item_length);
+
+void
+hb_buffer_add_utf32 (hb_buffer_t *buffer,
+ const uint32_t *text,
+ int text_length,
+ unsigned int item_offset,
+ int item_length);
+
+
+/* Clears any new items added at the end */
+hb_bool_t
+hb_buffer_set_length (hb_buffer_t *buffer,
+ unsigned int length);
+
+/* Return value valid as long as buffer not modified */
+unsigned int
+hb_buffer_get_length (hb_buffer_t *buffer);
+
+/* Getting glyphs out of the buffer */
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_info_t *
+hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
+ unsigned int *length);
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_position_t *
+hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
+ unsigned int *length);
+
+
+/* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
+ * The resulting clusters should behave identical to pre-reordering clusters.
+ * NOTE: This has nothing to do with Unicode normalization. */
+void
+hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
+
+
+/*
+ * Serialize
+ */
+
+typedef enum { /*< flags >*/
+ HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000,
+ HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001,
+ HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002,
+ HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004
+} hb_buffer_serialize_flags_t;
+
+typedef enum {
+ HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'),
+ HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'),
+ HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE
+} hb_buffer_serialize_format_t;
+
+/* len=-1 means str is NUL-terminated. */
+hb_buffer_serialize_format_t
+hb_buffer_serialize_format_from_string (const char *str, int len);
+
+const char *
+hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format);
+
+const char **
+hb_buffer_serialize_list_formats (void);
+
+/* Returns number of items, starting at start, that were serialized. */
+unsigned int
+hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed, /* May be NULL */
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags);
+
+hb_bool_t
+hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
+ const char *buf,
+ int buf_len, /* -1 means nul-terminated */
+ const char **end_ptr, /* May be NULL */
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format);
+
+
+HB_END_DECLS
+
+#endif /* HB_BUFFER_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh
new file mode 100644
index 0000000000..19b70b7e39
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_CACHE_PRIVATE_HH
+#define HB_CACHE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* Implements a lock-free cache for int->int functions. */
+
+template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
+struct hb_cache_t
+{
+ ASSERT_STATIC (key_bits >= cache_bits);
+ ASSERT_STATIC (key_bits + value_bits - cache_bits < 8 * sizeof (unsigned int));
+
+ inline void clear (void)
+ {
+ memset (values, 255, sizeof (values));
+ }
+
+ inline bool get (unsigned int key, unsigned int *value)
+ {
+ unsigned int k = key & ((1<<cache_bits)-1);
+ unsigned int v = values[k];
+ if ((v >> value_bits) != (key >> cache_bits))
+ return false;
+ *value = v & ((1<<value_bits)-1);
+ return true;
+ }
+
+ inline bool set (unsigned int key, unsigned int value)
+ {
+ if (unlikely ((key >> key_bits) || (value >> value_bits)))
+ return false; /* Overflows */
+ unsigned int k = key & ((1<<cache_bits)-1);
+ unsigned int v = ((key>>cache_bits)<<value_bits) | value;
+ values[k] = v;
+ return true;
+ }
+
+ private:
+ unsigned int values[1<<cache_bits];
+};
+
+typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
+typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
+
+
+#endif /* HB_CACHE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
new file mode 100644
index 0000000000..7c6d26290d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
@@ -0,0 +1,434 @@
+/*
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-version.h"
+
+#include "hb-mutex-private.hh"
+#include "hb-object-private.hh"
+
+#include <locale.h>
+
+
+/* hb_options_t */
+
+hb_options_union_t _hb_options;
+
+void
+_hb_options_init (void)
+{
+ hb_options_union_t u;
+ u.i = 0;
+ u.opts.initialized = 1;
+
+ char *c = getenv ("HB_OPTIONS");
+ u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
+
+ /* This is idempotent and threadsafe. */
+ _hb_options = u;
+}
+
+
+/* hb_tag_t */
+
+hb_tag_t
+hb_tag_from_string (const char *s, int len)
+{
+ char tag[4];
+ unsigned int i;
+
+ if (!s || !len || !*s)
+ return HB_TAG_NONE;
+
+ if (len < 0 || len > 4)
+ len = 4;
+ for (i = 0; i < (unsigned) len && s[i]; i++)
+ tag[i] = s[i];
+ for (; i < 4; i++)
+ tag[i] = ' ';
+
+ return HB_TAG_CHAR4 (tag);
+}
+
+void
+hb_tag_to_string (hb_tag_t tag, char *buf)
+{
+ buf[0] = (char) (uint8_t) (tag >> 24);
+ buf[1] = (char) (uint8_t) (tag >> 16);
+ buf[2] = (char) (uint8_t) (tag >> 8);
+ buf[3] = (char) (uint8_t) (tag >> 0);
+}
+
+
+/* hb_direction_t */
+
+const char direction_strings[][4] = {
+ "ltr",
+ "rtl",
+ "ttb",
+ "btt"
+};
+
+hb_direction_t
+hb_direction_from_string (const char *str, int len)
+{
+ if (unlikely (!str || !len || !*str))
+ return HB_DIRECTION_INVALID;
+
+ /* Lets match loosely: just match the first letter, such that
+ * all of "ltr", "left-to-right", etc work!
+ */
+ char c = TOLOWER (str[0]);
+ for (unsigned int i = 0; i < ARRAY_LENGTH (direction_strings); i++)
+ if (c == direction_strings[i][0])
+ return (hb_direction_t) (HB_DIRECTION_LTR + i);
+
+ return HB_DIRECTION_INVALID;
+}
+
+const char *
+hb_direction_to_string (hb_direction_t direction)
+{
+ if (likely ((unsigned int) (direction - HB_DIRECTION_LTR)
+ < ARRAY_LENGTH (direction_strings)))
+ return direction_strings[direction - HB_DIRECTION_LTR];
+
+ return "invalid";
+}
+
+
+/* hb_language_t */
+
+struct hb_language_impl_t {
+ const char s[1];
+};
+
+static const char canon_map[256] = {
+ 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
+ '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
+ 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
+};
+
+static hb_bool_t
+lang_equal (hb_language_t v1,
+ const void *v2)
+{
+ const unsigned char *p1 = (const unsigned char *) v1;
+ const unsigned char *p2 = (const unsigned char *) v2;
+
+ while (*p1 && *p1 == canon_map[*p2])
+ p1++, p2++;
+
+ return *p1 == canon_map[*p2];
+}
+
+#if 0
+static unsigned int
+lang_hash (const void *key)
+{
+ const unsigned char *p = key;
+ unsigned int h = 0;
+ while (canon_map[*p])
+ {
+ h = (h << 5) - h + canon_map[*p];
+ p++;
+ }
+
+ return h;
+}
+#endif
+
+
+struct hb_language_item_t {
+
+ struct hb_language_item_t *next;
+ hb_language_t lang;
+
+ inline bool operator == (const char *s) const {
+ return lang_equal (lang, s);
+ }
+
+ inline hb_language_item_t & operator = (const char *s) {
+ lang = (hb_language_t) strdup (s);
+ for (unsigned char *p = (unsigned char *) lang; *p; p++)
+ *p = canon_map[*p];
+
+ return *this;
+ }
+
+ void finish (void) { free (lang); }
+};
+
+
+/* Thread-safe lock-free language list */
+
+static hb_language_item_t *langs;
+
+static inline
+void free_langs (void)
+{
+ while (langs) {
+ hb_language_item_t *next = langs->next;
+ langs->finish ();
+ free (langs);
+ langs = next;
+ }
+}
+
+static hb_language_item_t *
+lang_find_or_insert (const char *key)
+{
+retry:
+ hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
+
+ for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
+ if (*lang == key)
+ return lang;
+
+ /* Not found; allocate one. */
+ hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t));
+ if (unlikely (!lang))
+ return NULL;
+ lang->next = first_lang;
+ *lang = key;
+
+ if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
+ free (lang);
+ goto retry;
+ }
+
+#ifdef HAVE_ATEXIT
+ if (!first_lang)
+ atexit (free_langs); /* First person registers atexit() callback. */
+#endif
+
+ return lang;
+}
+
+
+hb_language_t
+hb_language_from_string (const char *str, int len)
+{
+ if (!str || !len || !*str)
+ return HB_LANGUAGE_INVALID;
+
+ if (len >= 0) {
+ char strbuf[64];
+ len = MIN (len, (int) sizeof (strbuf) - 1);
+ str = (char *) memcpy (strbuf, str, len);
+ strbuf[len] = '\0';
+ }
+
+ hb_language_item_t *item = lang_find_or_insert (str);
+
+ return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
+}
+
+const char *
+hb_language_to_string (hb_language_t language)
+{
+ /* This is actually NULL-safe! */
+ return language->s;
+}
+
+hb_language_t
+hb_language_get_default (void)
+{
+ static hb_language_t default_language = HB_LANGUAGE_INVALID;
+
+ hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
+ if (unlikely (language == HB_LANGUAGE_INVALID)) {
+ language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1);
+ hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
+ }
+
+ return default_language;
+}
+
+
+/* hb_script_t */
+
+hb_script_t
+hb_script_from_iso15924_tag (hb_tag_t tag)
+{
+ if (unlikely (tag == HB_TAG_NONE))
+ return HB_SCRIPT_INVALID;
+
+ /* Be lenient, adjust case (one capital letter followed by three small letters) */
+ tag = (tag & 0xDFDFDFDF) | 0x00202020;
+
+ switch (tag) {
+
+ /* These graduated from the 'Q' private-area codes, but
+ * the old code is still aliased by Unicode, and the Qaai
+ * one in use by ICU. */
+ case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED;
+ case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
+
+ /* Script variants from http://unicode.org/iso15924/ */
+ case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
+ case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
+ case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
+ case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
+ case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC;
+ case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC;
+ }
+
+ /* If it looks right, just use the tag as a script */
+ if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060)
+ return (hb_script_t) tag;
+
+ /* Otherwise, return unknown */
+ return HB_SCRIPT_UNKNOWN;
+}
+
+hb_script_t
+hb_script_from_string (const char *s, int len)
+{
+ return hb_script_from_iso15924_tag (hb_tag_from_string (s, len));
+}
+
+hb_tag_t
+hb_script_to_iso15924_tag (hb_script_t script)
+{
+ return (hb_tag_t) script;
+}
+
+hb_direction_t
+hb_script_get_horizontal_direction (hb_script_t script)
+{
+ /* http://goo.gl/x9ilM */
+ switch ((hb_tag_t) script)
+ {
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_ARABIC:
+ case HB_SCRIPT_HEBREW:
+
+ /* Unicode-3.0 additions */
+ case HB_SCRIPT_SYRIAC:
+ case HB_SCRIPT_THAANA:
+
+ /* Unicode-4.0 additions */
+ case HB_SCRIPT_CYPRIOT:
+
+ /* Unicode-4.1 additions */
+ case HB_SCRIPT_KHAROSHTHI:
+
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_PHOENICIAN:
+ case HB_SCRIPT_NKO:
+
+ /* Unicode-5.1 additions */
+ case HB_SCRIPT_LYDIAN:
+
+ /* Unicode-5.2 additions */
+ case HB_SCRIPT_AVESTAN:
+ case HB_SCRIPT_IMPERIAL_ARAMAIC:
+ case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI:
+ case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN:
+ case HB_SCRIPT_OLD_SOUTH_ARABIAN:
+ case HB_SCRIPT_OLD_TURKIC:
+ case HB_SCRIPT_SAMARITAN:
+
+ /* Unicode-6.0 additions */
+ case HB_SCRIPT_MANDAIC:
+
+ /* Unicode-6.1 additions */
+ case HB_SCRIPT_MEROITIC_CURSIVE:
+ case HB_SCRIPT_MEROITIC_HIEROGLYPHS:
+
+ return HB_DIRECTION_RTL;
+ }
+
+ return HB_DIRECTION_LTR;
+}
+
+
+/* hb_user_data_array_t */
+
+bool
+hb_user_data_array_t::set (hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ if (!key)
+ return false;
+
+ if (replace) {
+ if (!data && !destroy) {
+ items.remove (key, lock);
+ return true;
+ }
+ }
+ hb_user_data_item_t item = {key, data, destroy};
+ bool ret = !!items.replace_or_insert (item, lock, replace);
+
+ return ret;
+}
+
+void *
+hb_user_data_array_t::get (hb_user_data_key_t *key)
+{
+ hb_user_data_item_t item = {NULL };
+
+ return items.find (key, &item, lock) ? item.data : NULL;
+}
+
+
+/* hb_version */
+
+void
+hb_version (unsigned int *major,
+ unsigned int *minor,
+ unsigned int *micro)
+{
+ *major = HB_VERSION_MAJOR;
+ *minor = HB_VERSION_MINOR;
+ *micro = HB_VERSION_MICRO;
+}
+
+const char *
+hb_version_string (void)
+{
+ return HB_VERSION_STRING;
+}
+
+hb_bool_t
+hb_version_check (unsigned int major,
+ unsigned int minor,
+ unsigned int micro)
+{
+ return HB_VERSION_CHECK (major, minor, micro);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h
new file mode 100644
index 0000000000..9079b2c046
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_COMMON_H
+#define HB_COMMON_H
+
+#ifndef HB_BEGIN_DECLS
+# ifdef __cplusplus
+# define HB_BEGIN_DECLS extern "C" {
+# define HB_END_DECLS }
+# else /* !__cplusplus */
+# define HB_BEGIN_DECLS
+# define HB_END_DECLS
+# endif /* !__cplusplus */
+#endif
+
+#if !defined (HB_DONT_DEFINE_STDINT)
+
+#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
+ defined (_sgi) || defined (__sun) || defined (sun) || \
+ defined (__digital__) || defined (__HP_cc)
+# include <inttypes.h>
+#elif defined (_AIX)
+# include <sys/inttypes.h>
+/* VS 2010 (_MSC_VER 1600) has stdint.h */
+#elif defined (_MSC_VER) && _MSC_VER < 1600
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+# include <stdint.h>
+#endif
+
+#endif
+
+HB_BEGIN_DECLS
+
+
+typedef int hb_bool_t;
+
+typedef uint32_t hb_codepoint_t;
+typedef int32_t hb_position_t;
+typedef uint32_t hb_mask_t;
+
+typedef union _hb_var_int_t {
+ uint32_t u32;
+ int32_t i32;
+ uint16_t u16[2];
+ int16_t i16[2];
+ uint8_t u8[4];
+ int8_t i8[4];
+} hb_var_int_t;
+
+
+/* hb_tag_t */
+
+typedef uint32_t hb_tag_t;
+
+#define HB_TAG(a,b,c,d) ((hb_tag_t)((((uint8_t)(a))<<24)|(((uint8_t)(b))<<16)|(((uint8_t)(c))<<8)|((uint8_t)(d))))
+#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
+
+#define HB_TAG_NONE HB_TAG(0,0,0,0)
+
+/* len=-1 means str is NUL-terminated. */
+hb_tag_t
+hb_tag_from_string (const char *str, int len);
+
+/* buf should have 4 bytes. */
+void
+hb_tag_to_string (hb_tag_t tag, char *buf);
+
+
+/* hb_direction_t */
+
+typedef enum {
+ HB_DIRECTION_INVALID = 0,
+ HB_DIRECTION_LTR = 4,
+ HB_DIRECTION_RTL,
+ HB_DIRECTION_TTB,
+ HB_DIRECTION_BTT
+} hb_direction_t;
+
+/* len=-1 means str is NUL-terminated */
+hb_direction_t
+hb_direction_from_string (const char *str, int len);
+
+const char *
+hb_direction_to_string (hb_direction_t direction);
+
+#define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
+#define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6)
+#define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4)
+#define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5)
+#define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
+#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1)) /* Direction must be valid */
+
+
+/* hb_language_t */
+
+typedef struct hb_language_impl_t *hb_language_t;
+
+/* len=-1 means str is NUL-terminated */
+hb_language_t
+hb_language_from_string (const char *str, int len);
+
+const char *
+hb_language_to_string (hb_language_t language);
+
+#define HB_LANGUAGE_INVALID ((hb_language_t) NULL)
+
+hb_language_t
+hb_language_get_default (void);
+
+
+/* hb_script_t */
+
+/* http://unicode.org/iso15924/ */
+/* http://goo.gl/x9ilM */
+/* Unicode Character Database property: Script (sc) */
+typedef enum
+{
+ /*1.1*/ HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'),
+ /*1.1*/ HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'),
+ /*5.0*/ HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'),
+
+ /*1.1*/ HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'),
+ /*1.1*/ HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'),
+ /*1.1*/ HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'),
+ /*1.1*/ HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'),
+ /*1.1*/ HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'),
+ /*1.1*/ HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'),
+ /*1.1*/ HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'),
+ /*1.1*/ HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'),
+ /*1.1*/ HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'),
+ /*1.1*/ HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'),
+ /*1.1*/ HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'),
+ /*1.1*/ HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'),
+ /*1.1*/ HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'),
+ /*1.1*/ HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'),
+ /*1.1*/ HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'),
+ /*1.1*/ HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'),
+ /*1.1*/ HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'),
+ /*1.1*/ HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'),
+ /*1.1*/ HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'),
+ /*1.1*/ HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'),
+ /*1.1*/ HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'),
+ /*1.1*/ HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'),
+
+ /*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'),
+
+ /*3.0*/ HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'),
+ /*3.0*/ HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'),
+ /*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'),
+ /*3.0*/ HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'),
+ /*3.0*/ HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'),
+ /*3.0*/ HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'),
+ /*3.0*/ HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'),
+ /*3.0*/ HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'),
+ /*3.0*/ HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'),
+ /*3.0*/ HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'),
+ /*3.0*/ HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'),
+ /*3.0*/ HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'),
+ /*3.0*/ HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'),
+ /*3.0*/ HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'),
+
+ /*3.1*/ HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'),
+ /*3.1*/ HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'),
+ /*3.1*/ HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'),
+
+ /*3.2*/ HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'),
+ /*3.2*/ HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'),
+ /*3.2*/ HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'),
+ /*3.2*/ HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'),
+
+ /*4.0*/ HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'),
+ /*4.0*/ HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'),
+ /*4.0*/ HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'),
+ /*4.0*/ HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'),
+ /*4.0*/ HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'),
+ /*4.0*/ HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'),
+ /*4.0*/ HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'),
+
+ /*4.1*/ HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'),
+ /*4.1*/ HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'),
+ /*4.1*/ HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'),
+ /*4.1*/ HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'),
+ /*4.1*/ HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'),
+ /*4.1*/ HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'),
+ /*4.1*/ HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'),
+ /*4.1*/ HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'),
+
+ /*5.0*/ HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'),
+ /*5.0*/ HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'),
+ /*5.0*/ HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'),
+ /*5.0*/ HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'),
+ /*5.0*/ HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'),
+
+ /*5.1*/ HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'),
+ /*5.1*/ HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'),
+ /*5.1*/ HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'),
+ /*5.1*/ HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'),
+ /*5.1*/ HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'),
+ /*5.1*/ HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'),
+ /*5.1*/ HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'),
+ /*5.1*/ HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'),
+ /*5.1*/ HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'),
+ /*5.1*/ HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'),
+ /*5.1*/ HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'),
+
+ /*5.2*/ HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'),
+ /*5.2*/ HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'),
+ /*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'),
+ /*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'),
+ /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'),
+ /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'),
+ /*5.2*/ HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'),
+ /*5.2*/ HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'),
+ /*5.2*/ HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'),
+ /*5.2*/ HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'),
+ /*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'),
+ /*5.2*/ HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'),
+ /*5.2*/ HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'),
+ /*5.2*/ HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'),
+ /*5.2*/ HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'),
+
+ /*6.0*/ HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'),
+ /*6.0*/ HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'),
+ /*6.0*/ HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'),
+
+ /*6.1*/ HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'),
+ /*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'),
+ /*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'),
+ /*6.1*/ HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'),
+ /*6.1*/ HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'),
+ /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
+ /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
+
+ /* No script set. */
+ /*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE
+} hb_script_t;
+
+/* These are moved out of hb_script_t because glib-mkenums chokes otherwise. */
+#if 0
+ /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
+ /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
+ /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
+ /*7.0*/ HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'),
+ /*7.0*/ HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'),
+ /*7.0*/ HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'),
+ /*7.0*/ HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'),
+ /*7.0*/ HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'),
+ /*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
+ /*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
+ /*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
+ /*7.0*/ HB_SCRIPT_MODI = ???
+ /*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
+ /*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
+ /*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
+ /*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
+ /*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
+ /*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
+ /*7.0*/ HB_SCRIPT_PAU_CIN_HAU = ???
+ /*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
+ /*7.0*/ HB_SCRIPT_SIDDHAM = ???
+ /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
+ /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
+#endif
+
+
+/* Script functions */
+
+hb_script_t
+hb_script_from_iso15924_tag (hb_tag_t tag);
+
+/* suger for tag_from_string() then script_from_iso15924_tag */
+/* len=-1 means s is NUL-terminated */
+hb_script_t
+hb_script_from_string (const char *s, int len);
+
+hb_tag_t
+hb_script_to_iso15924_tag (hb_script_t script);
+
+hb_direction_t
+hb_script_get_horizontal_direction (hb_script_t script);
+
+
+/* User data */
+
+typedef struct hb_user_data_key_t {
+ /*< private >*/
+ char unused;
+} hb_user_data_key_t;
+
+typedef void (*hb_destroy_func_t) (void *user_data);
+
+
+HB_END_DECLS
+
+#endif /* HB_COMMON_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h
new file mode 100644
index 0000000000..30ae4b1caf
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_DEPRECATED_H
+#define HB_DEPRECATED_H
+
+#include "hb-common.h"
+#include "hb-unicode.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+#ifndef HB_DISABLE_DEPRECATED
+
+#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS
+
+#define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT
+#define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT
+
+#endif
+
+HB_END_DECLS
+
+#endif /* HB_DEPRECATED_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
new file mode 100644
index 0000000000..b33be0e5fc
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2011 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FACE_PRIVATE_HH
+#define HB_FACE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-font.h"
+#include "hb-object-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+
+
+/*
+ * hb_face_t
+ */
+
+struct hb_face_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_bool_t immutable;
+
+ hb_reference_table_func_t reference_table_func;
+ void *user_data;
+ hb_destroy_func_t destroy;
+
+ unsigned int index;
+ mutable unsigned int upem;
+ mutable unsigned int num_glyphs;
+
+ struct hb_shaper_data_t shaper_data;
+
+ struct plan_node_t {
+ hb_shape_plan_t *shape_plan;
+ plan_node_t *next;
+ } *shape_plans;
+
+
+ inline hb_blob_t *reference_table (hb_tag_t tag) const
+ {
+ hb_blob_t *blob;
+
+ if (unlikely (!this || !reference_table_func))
+ return hb_blob_get_empty ();
+
+ blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
+ if (unlikely (!blob))
+ return hb_blob_get_empty ();
+
+ return blob;
+ }
+
+ inline HB_PURE_FUNC unsigned int get_upem (void) const
+ {
+ if (unlikely (!upem))
+ load_upem ();
+ return upem;
+ }
+
+ inline unsigned int get_num_glyphs (void) const
+ {
+ if (unlikely (num_glyphs == (unsigned int) -1))
+ load_num_glyphs ();
+ return num_glyphs;
+ }
+
+ private:
+ HB_INTERNAL void load_upem (void) const;
+ HB_INTERNAL void load_num_glyphs (void) const;
+};
+
+extern HB_INTERNAL const hb_face_t _hb_face_nil;
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+
+
+#endif /* HB_FACE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
new file mode 100644
index 0000000000..d8b9ed8c3f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
@@ -0,0 +1,311 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-ot-layout-private.hh"
+
+#include "hb-font-private.hh"
+#include "hb-blob.h"
+#include "hb-open-file-private.hh"
+#include "hb-ot-head-table.hh"
+#include "hb-ot-maxp-table.hh"
+
+#include "hb-cache-private.hh"
+
+#include <string.h>
+
+
+/*
+ * hb_face_t
+ */
+
+const hb_face_t _hb_face_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* immutable */
+
+ NULL, /* reference_table_func */
+ NULL, /* user_data */
+ NULL, /* destroy */
+
+ 0, /* index */
+ 1000, /* upem */
+ 0, /* num_glyphs */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ },
+
+ NULL, /* shape_plans */
+};
+
+
+hb_face_t *
+hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
+ void *user_data,
+ hb_destroy_func_t destroy)
+{
+ hb_face_t *face;
+
+ if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) {
+ if (destroy)
+ destroy (user_data);
+ return hb_face_get_empty ();
+ }
+
+ face->reference_table_func = reference_table_func;
+ face->user_data = user_data;
+ face->destroy = destroy;
+
+ face->upem = 0;
+ face->num_glyphs = (unsigned int) -1;
+
+ return face;
+}
+
+
+typedef struct hb_face_for_data_closure_t {
+ hb_blob_t *blob;
+ unsigned int index;
+} hb_face_for_data_closure_t;
+
+static hb_face_for_data_closure_t *
+_hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
+{
+ hb_face_for_data_closure_t *closure;
+
+ closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t));
+ if (unlikely (!closure))
+ return NULL;
+
+ closure->blob = blob;
+ closure->index = index;
+
+ return closure;
+}
+
+static void
+_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
+{
+ hb_blob_destroy (closure->blob);
+ free (closure);
+}
+
+static hb_blob_t *
+_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+ hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
+
+ if (tag == HB_TAG_NONE)
+ return hb_blob_reference (data->blob);
+
+ const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
+ const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
+
+ const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
+
+ hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
+
+ return blob;
+}
+
+hb_face_t *
+hb_face_create (hb_blob_t *blob,
+ unsigned int index)
+{
+ hb_face_t *face;
+
+ if (unlikely (!blob || !hb_blob_get_length (blob)))
+ return hb_face_get_empty ();
+
+ hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
+
+ if (unlikely (!closure))
+ return hb_face_get_empty ();
+
+ face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
+ closure,
+ (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
+
+ hb_face_set_index (face, index);
+
+ return face;
+}
+
+hb_face_t *
+hb_face_get_empty (void)
+{
+ return const_cast<hb_face_t *> (&_hb_face_nil);
+}
+
+
+hb_face_t *
+hb_face_reference (hb_face_t *face)
+{
+ return hb_object_reference (face);
+}
+
+void
+hb_face_destroy (hb_face_t *face)
+{
+ if (!hb_object_destroy (face)) return;
+
+ for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
+ {
+ hb_face_t::plan_node_t *next = node->next;
+ hb_shape_plan_destroy (node->shape_plan);
+ free (node);
+ node = next;
+ }
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+ if (face->destroy)
+ face->destroy (face->user_data);
+
+ free (face);
+}
+
+hb_bool_t
+hb_face_set_user_data (hb_face_t *face,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (face, key, data, destroy, replace);
+}
+
+void *
+hb_face_get_user_data (hb_face_t *face,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (face, key);
+}
+
+void
+hb_face_make_immutable (hb_face_t *face)
+{
+ if (hb_object_is_inert (face))
+ return;
+
+ face->immutable = true;
+}
+
+hb_bool_t
+hb_face_is_immutable (hb_face_t *face)
+{
+ return face->immutable;
+}
+
+
+hb_blob_t *
+hb_face_reference_table (hb_face_t *face,
+ hb_tag_t tag)
+{
+ return face->reference_table (tag);
+}
+
+hb_blob_t *
+hb_face_reference_blob (hb_face_t *face)
+{
+ return face->reference_table (HB_TAG_NONE);
+}
+
+void
+hb_face_set_index (hb_face_t *face,
+ unsigned int index)
+{
+ if (hb_object_is_inert (face))
+ return;
+
+ face->index = index;
+}
+
+unsigned int
+hb_face_get_index (hb_face_t *face)
+{
+ return face->index;
+}
+
+void
+hb_face_set_upem (hb_face_t *face,
+ unsigned int upem)
+{
+ if (hb_object_is_inert (face))
+ return;
+
+ face->upem = upem;
+}
+
+unsigned int
+hb_face_get_upem (hb_face_t *face)
+{
+ return face->get_upem ();
+}
+
+void
+hb_face_t::load_upem (void) const
+{
+ hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head));
+ const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob);
+ upem = head_table->get_upem ();
+ hb_blob_destroy (head_blob);
+}
+
+void
+hb_face_set_glyph_count (hb_face_t *face,
+ unsigned int glyph_count)
+{
+ if (hb_object_is_inert (face))
+ return;
+
+ face->num_glyphs = glyph_count;
+}
+
+unsigned int
+hb_face_get_glyph_count (hb_face_t *face)
+{
+ return face->get_num_glyphs ();
+}
+
+void
+hb_face_t::load_num_glyphs (void) const
+{
+ hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp));
+ const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
+ num_glyphs = maxp_table->get_num_glyphs ();
+ hb_blob_destroy (maxp_blob);
+}
+
+
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.h b/src/3rdparty/harfbuzz-ng/src/hb-face.h
new file mode 100644
index 0000000000..f682c468de
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_FACE_H
+#define HB_FACE_H
+
+#include "hb-common.h"
+#include "hb-blob.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * hb_face_t
+ */
+
+typedef struct hb_face_t hb_face_t;
+
+hb_face_t *
+hb_face_create (hb_blob_t *blob,
+ unsigned int index);
+
+typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data);
+
+/* calls destroy() when not needing user_data anymore */
+hb_face_t *
+hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
+ void *user_data,
+ hb_destroy_func_t destroy);
+
+hb_face_t *
+hb_face_get_empty (void);
+
+hb_face_t *
+hb_face_reference (hb_face_t *face);
+
+void
+hb_face_destroy (hb_face_t *face);
+
+hb_bool_t
+hb_face_set_user_data (hb_face_t *face,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+
+void *
+hb_face_get_user_data (hb_face_t *face,
+ hb_user_data_key_t *key);
+
+void
+hb_face_make_immutable (hb_face_t *face);
+
+hb_bool_t
+hb_face_is_immutable (hb_face_t *face);
+
+
+hb_blob_t *
+hb_face_reference_table (hb_face_t *face,
+ hb_tag_t tag);
+
+hb_blob_t *
+hb_face_reference_blob (hb_face_t *face);
+
+void
+hb_face_set_index (hb_face_t *face,
+ unsigned int index);
+
+unsigned int
+hb_face_get_index (hb_face_t *face);
+
+void
+hb_face_set_upem (hb_face_t *face,
+ unsigned int upem);
+
+unsigned int
+hb_face_get_upem (hb_face_t *face);
+
+void
+hb_face_set_glyph_count (hb_face_t *face,
+ unsigned int glyph_count);
+
+unsigned int
+hb_face_get_glyph_count (hb_face_t *face);
+
+
+HB_END_DECLS
+
+#endif /* HB_FACE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
new file mode 100644
index 0000000000..1a1fcfbda1
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2011 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#define HB_SHAPER fallback
+#include "hb-shaper-impl-private.hh"
+
+
+/*
+ * shaper face data
+ */
+
+struct hb_fallback_shaper_face_data_t {};
+
+hb_fallback_shaper_face_data_t *
+_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
+{
+ return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_fallback_shaper_font_data_t {};
+
+hb_fallback_shaper_font_data_t *
+_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
+{
+ return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_fallback_shaper_shape_plan_data_t {};
+
+hb_fallback_shaper_shape_plan_data_t *
+_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
+ const hb_feature_t *user_features HB_UNUSED,
+ unsigned int num_user_features HB_UNUSED)
+{
+ return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper
+ */
+
+hb_bool_t
+_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features HB_UNUSED,
+ unsigned int num_features HB_UNUSED)
+{
+ hb_codepoint_t space;
+ font->get_glyph (' ', 0, &space);
+
+ buffer->clear_positions ();
+
+ unsigned int count = buffer->len;
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (buffer->unicode->is_default_ignorable (buffer->info[i].codepoint)) {
+ buffer->info[i].codepoint = space;
+ buffer->pos[i].x_advance = 0;
+ buffer->pos[i].y_advance = 0;
+ continue;
+ }
+ font->get_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint);
+ font->get_glyph_advance_for_direction (buffer->info[i].codepoint,
+ buffer->props.direction,
+ &buffer->pos[i].x_advance,
+ &buffer->pos[i].y_advance);
+ font->subtract_glyph_origin_for_direction (buffer->info[i].codepoint,
+ buffer->props.direction,
+ &buffer->pos[i].x_offset,
+ &buffer->pos[i].y_offset);
+ }
+
+ if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+ hb_buffer_reverse (buffer);
+
+ return true;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
new file mode 100644
index 0000000000..620d05e8f9
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
@@ -0,0 +1,414 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2011 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FONT_PRIVATE_HH
+#define HB_FONT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-font.h"
+#include "hb-object-private.hh"
+#include "hb-face-private.hh"
+#include "hb-shaper-private.hh"
+
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
+ HB_FONT_FUNC_IMPLEMENT (glyph) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_name) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
+ /* ^--- Add new callbacks here */
+
+struct hb_font_funcs_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_bool_t immutable;
+
+ /* Don't access these directly. Call hb_font_get_*() instead. */
+
+ struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ } get;
+
+ struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ } user_data;
+
+ struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ } destroy;
+};
+
+
+
+/*
+ * hb_font_t
+ */
+
+struct hb_font_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_bool_t immutable;
+
+ hb_font_t *parent;
+ hb_face_t *face;
+
+ int x_scale;
+ int y_scale;
+
+ unsigned int x_ppem;
+ unsigned int y_ppem;
+
+ hb_font_funcs_t *klass;
+ void *user_data;
+ hb_destroy_func_t destroy;
+
+ struct hb_shaper_data_t shaper_data;
+
+
+ /* Convert from font-space to user-space */
+ inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
+ inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
+
+ /* Convert from parent-font user-space to our user-space */
+ inline hb_position_t parent_scale_x_distance (hb_position_t v) {
+ if (unlikely (parent && parent->x_scale != x_scale))
+ return v * (int64_t) this->x_scale / this->parent->x_scale;
+ return v;
+ }
+ inline hb_position_t parent_scale_y_distance (hb_position_t v) {
+ if (unlikely (parent && parent->y_scale != y_scale))
+ return v * (int64_t) this->y_scale / this->parent->y_scale;
+ return v;
+ }
+ inline hb_position_t parent_scale_x_position (hb_position_t v) {
+ return parent_scale_x_distance (v);
+ }
+ inline hb_position_t parent_scale_y_position (hb_position_t v) {
+ return parent_scale_y_distance (v);
+ }
+
+ inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
+ *x = parent_scale_x_distance (*x);
+ *y = parent_scale_y_distance (*y);
+ }
+ inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
+ *x = parent_scale_x_position (*x);
+ *y = parent_scale_y_position (*y);
+ }
+
+
+ /* Public getters */
+
+ inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph)
+ {
+ *glyph = 0;
+ return klass->get.glyph (this, user_data,
+ unicode, variation_selector, glyph,
+ klass->user_data.glyph);
+ }
+
+ inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
+ {
+ return klass->get.glyph_h_advance (this, user_data,
+ glyph,
+ klass->user_data.glyph_h_advance);
+ }
+
+ inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
+ {
+ return klass->get.glyph_v_advance (this, user_data,
+ glyph,
+ klass->user_data.glyph_v_advance);
+ }
+
+ inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = *y = 0;
+ return klass->get.glyph_h_origin (this, user_data,
+ glyph, x, y,
+ klass->user_data.glyph_h_origin);
+ }
+
+ inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = *y = 0;
+ return klass->get.glyph_v_origin (this, user_data,
+ glyph, x, y,
+ klass->user_data.glyph_v_origin);
+ }
+
+ inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+ {
+ return klass->get.glyph_h_kerning (this, user_data,
+ left_glyph, right_glyph,
+ klass->user_data.glyph_h_kerning);
+ }
+
+ inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+ {
+ return klass->get.glyph_v_kerning (this, user_data,
+ left_glyph, right_glyph,
+ klass->user_data.glyph_v_kerning);
+ }
+
+ inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents)
+ {
+ memset (extents, 0, sizeof (*extents));
+ return klass->get.glyph_extents (this, user_data,
+ glyph,
+ extents,
+ klass->user_data.glyph_extents);
+ }
+
+ inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = *y = 0;
+ return klass->get.glyph_contour_point (this, user_data,
+ glyph, point_index,
+ x, y,
+ klass->user_data.glyph_contour_point);
+ }
+
+ inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
+ char *name, unsigned int size)
+ {
+ if (size) *name = '\0';
+ return klass->get.glyph_name (this, user_data,
+ glyph,
+ name, size,
+ klass->user_data.glyph_name);
+ }
+
+ inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph)
+ {
+ *glyph = 0;
+ if (len == -1) len = strlen (name);
+ return klass->get.glyph_from_name (this, user_data,
+ name, len,
+ glyph,
+ klass->user_data.glyph_from_name);
+ }
+
+
+ /* A bit higher-level, and with fallback */
+
+ inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+ *x = get_glyph_h_advance (glyph);
+ *y = 0;
+ } else {
+ *x = 0;
+ *y = get_glyph_v_advance (glyph);
+ }
+ }
+
+ /* Internal only */
+ inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = get_glyph_h_advance (glyph) / 2;
+
+ /* TODO use font_metics.ascent */
+ *y = y_scale;
+ }
+
+ inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+ {
+ if (!get_glyph_h_origin (glyph, x, y) &&
+ get_glyph_v_origin (glyph, x, y))
+ {
+ hb_position_t dx, dy;
+ guess_v_origin_minus_h_origin (glyph, &dx, &dy);
+ *x -= dx; *y -= dy;
+ }
+ }
+ else
+ {
+ if (!get_glyph_v_origin (glyph, x, y) &&
+ get_glyph_h_origin (glyph, x, y))
+ {
+ hb_position_t dx, dy;
+ guess_v_origin_minus_h_origin (glyph, &dx, &dy);
+ *x += dx; *y += dy;
+ }
+ }
+ }
+
+ inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
+
+ *x += origin_x;
+ *y += origin_y;
+ }
+
+ inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
+
+ *x -= origin_x;
+ *y -= origin_y;
+ }
+
+ inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+ *x = get_glyph_h_kerning (first_glyph, second_glyph);
+ *y = 0;
+ } else {
+ *x = 0;
+ *y = get_glyph_v_kerning (first_glyph, second_glyph);
+ }
+ }
+
+ inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_glyph_extents_t *extents)
+ {
+ hb_bool_t ret = get_glyph_extents (glyph, extents);
+
+ if (ret)
+ subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
+
+ return ret;
+ }
+
+ inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
+
+ if (ret)
+ subtract_glyph_origin_for_direction (glyph, direction, x, y);
+
+ return ret;
+ }
+
+ /* Generates gidDDD if glyph has no name. */
+ inline void
+ glyph_to_string (hb_codepoint_t glyph,
+ char *s, unsigned int size)
+ {
+ if (get_glyph_name (glyph, s, size)) return;
+
+ if (size && snprintf (s, size, "gid%u", glyph) < 0)
+ *s = '\0';
+ }
+
+ /* Parses gidDDD and uniUUUU strings automatically. */
+ inline hb_bool_t
+ glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph)
+ {
+ if (get_glyph_from_name (s, len, glyph)) return true;
+
+ if (len == -1) len = strlen (s);
+
+ /* Straight glyph index. */
+ if (hb_codepoint_parse (s, len, 10, glyph))
+ return true;
+
+ if (len > 3)
+ {
+ /* gidDDD syntax for glyph indices. */
+ if (0 == strncmp (s, "gid", 3) &&
+ hb_codepoint_parse (s + 3, len - 3, 10, glyph))
+ return true;
+
+ /* uniUUUU and other Unicode character indices. */
+ hb_codepoint_t unichar;
+ if (0 == strncmp (s, "uni", 3) &&
+ hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
+ get_glyph (unichar, 0, glyph))
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ inline hb_position_t em_scale (int16_t v, int scale)
+ {
+ unsigned int upem = face->get_upem ();
+ return (v * (int64_t) scale + upem / 2) / upem;
+ }
+};
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+
+
+#endif /* HB_FONT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
new file mode 100644
index 0000000000..c2f6f6ddd5
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
@@ -0,0 +1,739 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-ot-layout-private.hh"
+
+#include "hb-font-private.hh"
+#include "hb-blob.h"
+#include "hb-open-file-private.hh"
+#include "hb-ot-head-table.hh"
+#include "hb-ot-maxp-table.hh"
+
+#include "hb-cache-private.hh"
+
+#include <string.h>
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+static hb_bool_t
+hb_font_get_glyph_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent)
+ return font->parent->get_glyph (unicode, variation_selector, glyph);
+
+ *glyph = 0;
+ return false;
+}
+
+static hb_position_t
+hb_font_get_glyph_h_advance_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent)
+ return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
+
+ return font->x_scale;
+}
+
+static hb_position_t
+hb_font_get_glyph_v_advance_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent)
+ return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
+
+ return font->y_scale;
+}
+
+static hb_bool_t
+hb_font_get_glyph_h_origin_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent) {
+ hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
+ if (ret)
+ font->parent_scale_position (x, y);
+ return ret;
+ }
+
+ *x = *y = 0;
+ return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_v_origin_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent) {
+ hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
+ if (ret)
+ font->parent_scale_position (x, y);
+ return ret;
+ }
+
+ *x = *y = 0;
+ return false;
+}
+
+static hb_position_t
+hb_font_get_glyph_h_kerning_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t left_glyph,
+ hb_codepoint_t right_glyph,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent)
+ return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
+
+ return 0;
+}
+
+static hb_position_t
+hb_font_get_glyph_v_kerning_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t top_glyph,
+ hb_codepoint_t bottom_glyph,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent)
+ return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
+
+ return 0;
+}
+
+static hb_bool_t
+hb_font_get_glyph_extents_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent) {
+ hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
+ if (ret) {
+ font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
+ font->parent_scale_distance (&extents->width, &extents->height);
+ }
+ return ret;
+ }
+
+ memset (extents, 0, sizeof (*extents));
+ return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_contour_point_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ unsigned int point_index,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent) {
+ hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
+ if (ret)
+ font->parent_scale_position (x, y);
+ return ret;
+ }
+
+ *x = *y = 0;
+ return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_name_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent)
+ return font->parent->get_glyph_name (glyph, name, size);
+
+ if (size) *name = '\0';
+ return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_from_name_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ const char *name, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph,
+ void *user_data HB_UNUSED)
+{
+ if (font->parent)
+ return font->parent->get_glyph_from_name (name, len, glyph);
+
+ *glyph = 0;
+ return false;
+}
+
+
+static const hb_font_funcs_t _hb_font_funcs_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* immutable */
+
+ {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ }
+};
+
+
+hb_font_funcs_t *
+hb_font_funcs_create (void)
+{
+ hb_font_funcs_t *ffuncs;
+
+ if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
+ return hb_font_funcs_get_empty ();
+
+ ffuncs->get = _hb_font_funcs_nil.get;
+
+ return ffuncs;
+}
+
+hb_font_funcs_t *
+hb_font_funcs_get_empty (void)
+{
+ return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
+}
+
+hb_font_funcs_t *
+hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
+{
+ return hb_object_reference (ffuncs);
+}
+
+void
+hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
+{
+ if (!hb_object_destroy (ffuncs)) return;
+
+#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
+ ffuncs->destroy.name (ffuncs->user_data.name);
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+
+ free (ffuncs);
+}
+
+hb_bool_t
+hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
+}
+
+void *
+hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (ffuncs, key);
+}
+
+
+void
+hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
+{
+ if (hb_object_is_inert (ffuncs))
+ return;
+
+ ffuncs->immutable = true;
+}
+
+hb_bool_t
+hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
+{
+ return ffuncs->immutable;
+}
+
+
+#define HB_FONT_FUNC_IMPLEMENT(name) \
+ \
+void \
+hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
+ hb_font_get_##name##_func_t func, \
+ void *user_data, \
+ hb_destroy_func_t destroy) \
+{ \
+ if (ffuncs->immutable) { \
+ if (destroy) \
+ destroy (user_data); \
+ return; \
+ } \
+ \
+ if (ffuncs->destroy.name) \
+ ffuncs->destroy.name (ffuncs->user_data.name); \
+ \
+ if (func) { \
+ ffuncs->get.name = func; \
+ ffuncs->user_data.name = user_data; \
+ ffuncs->destroy.name = destroy; \
+ } else { \
+ ffuncs->get.name = hb_font_get_##name##_nil; \
+ ffuncs->user_data.name = NULL; \
+ ffuncs->destroy.name = NULL; \
+ } \
+}
+
+HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+
+
+/* Public getters */
+
+hb_bool_t
+hb_font_get_glyph (hb_font_t *font,
+ hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph)
+{
+ return font->get_glyph (unicode, variation_selector, glyph);
+}
+
+hb_position_t
+hb_font_get_glyph_h_advance (hb_font_t *font,
+ hb_codepoint_t glyph)
+{
+ return font->get_glyph_h_advance (glyph);
+}
+
+hb_position_t
+hb_font_get_glyph_v_advance (hb_font_t *font,
+ hb_codepoint_t glyph)
+{
+ return font->get_glyph_v_advance (glyph);
+}
+
+hb_bool_t
+hb_font_get_glyph_h_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->get_glyph_h_origin (glyph, x, y);
+}
+
+hb_bool_t
+hb_font_get_glyph_v_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->get_glyph_v_origin (glyph, x, y);
+}
+
+hb_position_t
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+ hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+{
+ return font->get_glyph_h_kerning (left_glyph, right_glyph);
+}
+
+hb_position_t
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+ hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+{
+ return font->get_glyph_v_kerning (left_glyph, right_glyph);
+}
+
+hb_bool_t
+hb_font_get_glyph_extents (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents)
+{
+ return font->get_glyph_extents (glyph, extents);
+}
+
+hb_bool_t
+hb_font_get_glyph_contour_point (hb_font_t *font,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->get_glyph_contour_point (glyph, point_index, x, y);
+}
+
+hb_bool_t
+hb_font_get_glyph_name (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size)
+{
+ return font->get_glyph_name (glyph, name, size);
+}
+
+hb_bool_t
+hb_font_get_glyph_from_name (hb_font_t *font,
+ const char *name, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph)
+{
+ return font->get_glyph_from_name (name, len, glyph);
+}
+
+
+/* A bit higher-level, and with fallback */
+
+void
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->get_glyph_advance_for_direction (glyph, direction, x, y);
+}
+
+void
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->get_glyph_origin_for_direction (glyph, direction, x, y);
+}
+
+void
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->add_glyph_origin_for_direction (glyph, direction, x, y);
+}
+
+void
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
+}
+
+void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+ hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
+}
+
+hb_bool_t
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_glyph_extents_t *extents)
+{
+ return font->get_glyph_extents_for_origin (glyph, direction, extents);
+}
+
+hb_bool_t
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+{
+ return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
+}
+
+/* Generates gidDDD if glyph has no name. */
+void
+hb_font_glyph_to_string (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *s, unsigned int size)
+{
+ font->glyph_to_string (glyph, s, size);
+}
+
+/* Parses gidDDD and uniUUUU strings automatically. */
+hb_bool_t
+hb_font_glyph_from_string (hb_font_t *font,
+ const char *s, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph)
+{
+ return font->glyph_from_string (s, len, glyph);
+}
+
+
+/*
+ * hb_font_t
+ */
+
+hb_font_t *
+hb_font_create (hb_face_t *face)
+{
+ hb_font_t *font;
+
+ if (unlikely (!face))
+ face = hb_face_get_empty ();
+ if (unlikely (hb_object_is_inert (face)))
+ return hb_font_get_empty ();
+ if (!(font = hb_object_create<hb_font_t> ()))
+ return hb_font_get_empty ();
+
+ hb_face_make_immutable (face);
+ font->face = hb_face_reference (face);
+ font->klass = hb_font_funcs_get_empty ();
+
+ return font;
+}
+
+hb_font_t *
+hb_font_create_sub_font (hb_font_t *parent)
+{
+ if (unlikely (!parent))
+ return hb_font_get_empty ();
+
+ hb_font_t *font = hb_font_create (parent->face);
+
+ if (unlikely (hb_object_is_inert (font)))
+ return font;
+
+ hb_font_make_immutable (parent);
+ font->parent = hb_font_reference (parent);
+
+ font->x_scale = parent->x_scale;
+ font->y_scale = parent->y_scale;
+ font->x_ppem = parent->x_ppem;
+ font->y_ppem = parent->y_ppem;
+
+ return font;
+}
+
+hb_font_t *
+hb_font_get_empty (void)
+{
+ static const hb_font_t _hb_font_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* immutable */
+
+ NULL, /* parent */
+ const_cast<hb_face_t *> (&_hb_face_nil),
+
+ 0, /* x_scale */
+ 0, /* y_scale */
+
+ 0, /* x_ppem */
+ 0, /* y_ppem */
+
+ const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
+ NULL, /* user_data */
+ NULL, /* destroy */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
+ };
+
+ return const_cast<hb_font_t *> (&_hb_font_nil);
+}
+
+hb_font_t *
+hb_font_reference (hb_font_t *font)
+{
+ return hb_object_reference (font);
+}
+
+void
+hb_font_destroy (hb_font_t *font)
+{
+ if (!hb_object_destroy (font)) return;
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+ if (font->destroy)
+ font->destroy (font->user_data);
+
+ hb_font_destroy (font->parent);
+ hb_face_destroy (font->face);
+ hb_font_funcs_destroy (font->klass);
+
+ free (font);
+}
+
+hb_bool_t
+hb_font_set_user_data (hb_font_t *font,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (font, key, data, destroy, replace);
+}
+
+void *
+hb_font_get_user_data (hb_font_t *font,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (font, key);
+}
+
+void
+hb_font_make_immutable (hb_font_t *font)
+{
+ if (hb_object_is_inert (font))
+ return;
+
+ font->immutable = true;
+}
+
+hb_bool_t
+hb_font_is_immutable (hb_font_t *font)
+{
+ return font->immutable;
+}
+
+hb_font_t *
+hb_font_get_parent (hb_font_t *font)
+{
+ return font->parent;
+}
+
+hb_face_t *
+hb_font_get_face (hb_font_t *font)
+{
+ return font->face;
+}
+
+
+void
+hb_font_set_funcs (hb_font_t *font,
+ hb_font_funcs_t *klass,
+ void *user_data,
+ hb_destroy_func_t destroy)
+{
+ if (font->immutable) {
+ if (destroy)
+ destroy (user_data);
+ return;
+ }
+
+ if (font->destroy)
+ font->destroy (font->user_data);
+
+ if (!klass)
+ klass = hb_font_funcs_get_empty ();
+
+ hb_font_funcs_reference (klass);
+ hb_font_funcs_destroy (font->klass);
+ font->klass = klass;
+ font->user_data = user_data;
+ font->destroy = destroy;
+}
+
+void
+hb_font_set_funcs_data (hb_font_t *font,
+ void *user_data,
+ hb_destroy_func_t destroy)
+{
+ /* Destroy user_data? */
+ if (font->immutable) {
+ if (destroy)
+ destroy (user_data);
+ return;
+ }
+
+ if (font->destroy)
+ font->destroy (font->user_data);
+
+ font->user_data = user_data;
+ font->destroy = destroy;
+}
+
+
+void
+hb_font_set_scale (hb_font_t *font,
+ int x_scale,
+ int y_scale)
+{
+ if (font->immutable)
+ return;
+
+ font->x_scale = x_scale;
+ font->y_scale = y_scale;
+}
+
+void
+hb_font_get_scale (hb_font_t *font,
+ int *x_scale,
+ int *y_scale)
+{
+ if (x_scale) *x_scale = font->x_scale;
+ if (y_scale) *y_scale = font->y_scale;
+}
+
+void
+hb_font_set_ppem (hb_font_t *font,
+ unsigned int x_ppem,
+ unsigned int y_ppem)
+{
+ if (font->immutable)
+ return;
+
+ font->x_ppem = x_ppem;
+ font->y_ppem = y_ppem;
+}
+
+void
+hb_font_get_ppem (hb_font_t *font,
+ unsigned int *x_ppem,
+ unsigned int *y_ppem)
+{
+ if (x_ppem) *x_ppem = font->x_ppem;
+ if (y_ppem) *y_ppem = font->y_ppem;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h
new file mode 100644
index 0000000000..3a0c001b98
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h
@@ -0,0 +1,381 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_FONT_H
+#define HB_FONT_H
+
+#include "hb-common.h"
+#include "hb-face.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct hb_font_t hb_font_t;
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+typedef struct hb_font_funcs_t hb_font_funcs_t;
+
+hb_font_funcs_t *
+hb_font_funcs_create (void);
+
+hb_font_funcs_t *
+hb_font_funcs_get_empty (void);
+
+hb_font_funcs_t *
+hb_font_funcs_reference (hb_font_funcs_t *ffuncs);
+
+void
+hb_font_funcs_destroy (hb_font_funcs_t *ffuncs);
+
+hb_bool_t
+hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+
+void *
+hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
+ hb_user_data_key_t *key);
+
+
+void
+hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs);
+
+hb_bool_t
+hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
+
+
+/* glyph extents */
+
+typedef struct hb_glyph_extents_t
+{
+ hb_position_t x_bearing;
+ hb_position_t y_bearing;
+ hb_position_t width;
+ hb_position_t height;
+} hb_glyph_extents_t;
+
+
+/* func types */
+
+typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
+ hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph,
+ void *user_data);
+
+
+typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ void *user_data);
+typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
+typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
+
+typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y,
+ void *user_data);
+typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
+typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
+
+typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
+ hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+ void *user_data);
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
+
+
+typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents,
+ void *user_data);
+typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_position_t *x, hb_position_t *y,
+ void *user_data);
+
+
+typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size,
+ void *user_data);
+typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data,
+ const char *name, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph,
+ void *user_data);
+
+
+/* func setters */
+
+void
+hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_func_t glyph_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_h_advance_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+void
+hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_v_advance_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_h_origin_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+void
+hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_v_origin_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_h_kerning_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+void
+hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_v_kerning_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_extents_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+void
+hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_contour_point_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_name_func_t glyph_func,
+ void *user_data, hb_destroy_func_t destroy);
+void
+hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_from_name_func_t glyph_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+
+/* func dispatch */
+
+hb_bool_t
+hb_font_get_glyph (hb_font_t *font,
+ hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph);
+
+hb_position_t
+hb_font_get_glyph_h_advance (hb_font_t *font,
+ hb_codepoint_t glyph);
+hb_position_t
+hb_font_get_glyph_v_advance (hb_font_t *font,
+ hb_codepoint_t glyph);
+
+hb_bool_t
+hb_font_get_glyph_h_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y);
+hb_bool_t
+hb_font_get_glyph_v_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y);
+
+hb_position_t
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+ hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
+hb_position_t
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+ hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
+
+hb_bool_t
+hb_font_get_glyph_extents (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents);
+
+hb_bool_t
+hb_font_get_glyph_contour_point (hb_font_t *font,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_position_t *x, hb_position_t *y);
+
+hb_bool_t
+hb_font_get_glyph_name (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size);
+hb_bool_t
+hb_font_get_glyph_from_name (hb_font_t *font,
+ const char *name, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph);
+
+
+/* high-level funcs, with fallback */
+
+void
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y);
+void
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y);
+void
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y);
+void
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y);
+
+void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+ hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y);
+
+hb_bool_t
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_glyph_extents_t *extents);
+
+hb_bool_t
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y);
+
+/* Generates gidDDD if glyph has no name. */
+void
+hb_font_glyph_to_string (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *s, unsigned int size);
+/* Parses gidDDD and uniUUUU strings automatically. */
+hb_bool_t
+hb_font_glyph_from_string (hb_font_t *font,
+ const char *s, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph);
+
+
+/*
+ * hb_font_t
+ */
+
+/* Fonts are very light-weight objects */
+
+hb_font_t *
+hb_font_create (hb_face_t *face);
+
+hb_font_t *
+hb_font_create_sub_font (hb_font_t *parent);
+
+hb_font_t *
+hb_font_get_empty (void);
+
+hb_font_t *
+hb_font_reference (hb_font_t *font);
+
+void
+hb_font_destroy (hb_font_t *font);
+
+hb_bool_t
+hb_font_set_user_data (hb_font_t *font,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+
+void *
+hb_font_get_user_data (hb_font_t *font,
+ hb_user_data_key_t *key);
+
+void
+hb_font_make_immutable (hb_font_t *font);
+
+hb_bool_t
+hb_font_is_immutable (hb_font_t *font);
+
+hb_font_t *
+hb_font_get_parent (hb_font_t *font);
+
+hb_face_t *
+hb_font_get_face (hb_font_t *font);
+
+
+void
+hb_font_set_funcs (hb_font_t *font,
+ hb_font_funcs_t *klass,
+ void *font_data,
+ hb_destroy_func_t destroy);
+
+/* Be *very* careful with this function! */
+void
+hb_font_set_funcs_data (hb_font_t *font,
+ void *font_data,
+ hb_destroy_func_t destroy);
+
+
+void
+hb_font_set_scale (hb_font_t *font,
+ int x_scale,
+ int y_scale);
+
+void
+hb_font_get_scale (hb_font_t *font,
+ int *x_scale,
+ int *y_scale);
+
+/*
+ * A zero value means "no hinting in that direction"
+ */
+void
+hb_font_set_ppem (hb_font_t *font,
+ unsigned int x_ppem,
+ unsigned int y_ppem);
+
+void
+hb_font_get_ppem (hb_font_t *font,
+ unsigned int *x_ppem,
+ unsigned int *y_ppem);
+
+
+HB_END_DECLS
+
+#endif /* HB_FONT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
new file mode 100644
index 0000000000..0fb21c2e86
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Contributor(s):
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_MUTEX_PRIVATE_HH
+#define HB_MUTEX_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* mutex */
+
+/* We need external help for these */
+
+#if 0
+
+
+#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+typedef CRITICAL_SECTION hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 }
+#define hb_mutex_impl_init(M) InitializeCriticalSection (M)
+#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
+#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
+#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
+
+
+#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
+
+#include <pthread.h>
+typedef pthread_mutex_t hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT PTHREAD_MUTEX_INITIALIZER
+#define hb_mutex_impl_init(M) pthread_mutex_init (M, NULL)
+#define hb_mutex_impl_lock(M) pthread_mutex_lock (M)
+#define hb_mutex_impl_unlock(M) pthread_mutex_unlock (M)
+#define hb_mutex_impl_finish(M) pthread_mutex_destroy (M)
+
+
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
+
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
+#else
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
+#endif
+
+/* This actually is not a totally awful implementation. */
+typedef volatile int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT 0
+#define hb_mutex_impl_init(M) *(M) = 0
+#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
+#define hb_mutex_impl_unlock(M) __sync_lock_release (M)
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
+
+
+#elif !defined(HB_NO_MT)
+
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
+#else
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
+#endif
+
+#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
+typedef volatile int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT 0
+#define hb_mutex_impl_init(M) *(M) = 0
+#define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
+#define hb_mutex_impl_unlock(M) (*(M))--;
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
+
+
+#else /* HB_NO_MT */
+
+typedef int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT 0
+#define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_lock(M) HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
+
+#endif
+
+
+#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT}
+struct hb_mutex_t
+{
+ /* TODO Add tracing. */
+
+ hb_mutex_impl_t m;
+
+ inline void init (void) { hb_mutex_impl_init (&m); }
+ inline void lock (void) { hb_mutex_impl_lock (&m); }
+ inline void unlock (void) { hb_mutex_impl_unlock (&m); }
+ inline void finish (void) { hb_mutex_impl_finish (&m); }
+};
+
+
+#endif /* HB_MUTEX_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
new file mode 100644
index 0000000000..8a9ae34dbe
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
@@ -0,0 +1,227 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Contributor(s):
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OBJECT_PRIVATE_HH
+#define HB_OBJECT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-atomic-private.hh"
+#include "hb-mutex-private.hh"
+
+
+/* Debug */
+
+#ifndef HB_DEBUG_OBJECT
+#define HB_DEBUG_OBJECT (HB_DEBUG+0)
+#endif
+
+
+/* reference_count */
+
+#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
+#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
+struct hb_reference_count_t
+{
+ hb_atomic_int_t ref_count;
+
+ inline void init (int v) { ref_count = v; }
+ inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); }
+ inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); }
+ inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; }
+
+ inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; }
+
+};
+
+
+/* user_data */
+
+#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
+struct hb_user_data_array_t
+{
+ /* TODO Add tracing. */
+
+ struct hb_user_data_item_t {
+ hb_user_data_key_t *key;
+ void *data;
+ hb_destroy_func_t destroy;
+
+ inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
+ inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
+
+ void finish (void) { if (destroy) destroy (data); }
+ };
+
+ hb_mutex_t lock;
+ hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
+
+ inline void init (void) { lock.init (); items.init (); }
+
+ HB_INTERNAL bool set (hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+ HB_INTERNAL void *get (hb_user_data_key_t *key);
+
+ inline void finish (void) { items.finish (lock); lock.finish (); }
+};
+
+
+/* object_header */
+
+struct hb_object_header_t
+{
+ hb_reference_count_t ref_count;
+ hb_user_data_array_t user_data;
+
+#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT}
+
+ static inline void *create (unsigned int size) {
+ hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
+
+ if (likely (obj))
+ obj->init ();
+
+ return obj;
+ }
+
+ inline void init (void) {
+ ref_count.init (1);
+ user_data.init ();
+ }
+
+ inline bool is_inert (void) const {
+ return unlikely (ref_count.is_invalid ());
+ }
+
+ inline void reference (void) {
+ if (unlikely (!this || this->is_inert ()))
+ return;
+ ref_count.inc ();
+ }
+
+ inline bool destroy (void) {
+ if (unlikely (!this || this->is_inert ()))
+ return false;
+ if (ref_count.dec () != 1)
+ return false;
+
+ ref_count.finish (); /* Do this before user_data */
+ user_data.finish ();
+
+ return true;
+ }
+
+ inline bool set_user_data (hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy_func,
+ hb_bool_t replace) {
+ if (unlikely (!this || this->is_inert ()))
+ return false;
+
+ return user_data.set (key, data, destroy_func, replace);
+ }
+
+ inline void *get_user_data (hb_user_data_key_t *key) {
+ if (unlikely (!this || this->is_inert ()))
+ return NULL;
+
+ return user_data.get (key);
+ }
+
+ inline void trace (const char *function) const {
+ if (unlikely (!this)) return;
+ /* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only
+ * prints the class name and throws away the template info. */
+ DEBUG_MSG (OBJECT, (void *) this,
+ "%s refcount=%d",
+ function,
+ this ? ref_count.ref_count : 0);
+ }
+
+ private:
+ ASSERT_POD ();
+};
+
+
+/* object */
+
+template <typename Type>
+static inline void hb_object_trace (const Type *obj, const char *function)
+{
+ obj->header.trace (function);
+}
+template <typename Type>
+static inline Type *hb_object_create (void)
+{
+ Type *obj = (Type *) hb_object_header_t::create (sizeof (Type));
+ hb_object_trace (obj, HB_FUNC);
+ return obj;
+}
+template <typename Type>
+static inline bool hb_object_is_inert (const Type *obj)
+{
+ return unlikely (obj->header.is_inert ());
+}
+template <typename Type>
+static inline Type *hb_object_reference (Type *obj)
+{
+ hb_object_trace (obj, HB_FUNC);
+ obj->header.reference ();
+ return obj;
+}
+template <typename Type>
+static inline bool hb_object_destroy (Type *obj)
+{
+ hb_object_trace (obj, HB_FUNC);
+ return obj->header.destroy ();
+}
+template <typename Type>
+static inline bool hb_object_set_user_data (Type *obj,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return obj->header.set_user_data (key, data, destroy, replace);
+}
+
+template <typename Type>
+static inline void *hb_object_get_user_data (Type *obj,
+ hb_user_data_key_t *key)
+{
+ return obj->header.get_user_data (key);
+}
+
+
+#endif /* HB_OBJECT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
new file mode 100644
index 0000000000..250504ae20
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OPEN_FILE_PRIVATE_HH
+#define HB_OPEN_FILE_PRIVATE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ *
+ * The OpenType Font File
+ *
+ */
+
+
+/*
+ * Organization of an OpenType Font
+ */
+
+struct OpenTypeFontFile;
+struct OffsetTable;
+struct TTCHeader;
+
+
+typedef struct TableRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ Tag tag; /* 4-byte identifier. */
+ CheckSum checkSum; /* CheckSum for this table. */
+ ULONG offset; /* Offset from beginning of TrueType font
+ * file. */
+ ULONG length; /* Length of this table. */
+ public:
+ DEFINE_SIZE_STATIC (16);
+} OpenTypeTable;
+
+typedef struct OffsetTable
+{
+ friend struct OpenTypeFontFile;
+
+ inline unsigned int get_table_count (void) const
+ { return numTables; }
+ inline const TableRecord& get_table (unsigned int i) const
+ {
+ if (unlikely (i >= numTables)) return Null(TableRecord);
+ return tables[i];
+ }
+ inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
+ {
+ Tag t;
+ t.set (tag);
+ unsigned int count = numTables;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (t == tables[i].tag)
+ {
+ if (table_index) *table_index = i;
+ return true;
+ }
+ }
+ if (table_index) *table_index = Index::NOT_FOUND_INDEX;
+ return false;
+ }
+ inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
+ {
+ unsigned int table_index;
+ find_table_index (tag, &table_index);
+ return get_table (table_index);
+ }
+
+ public:
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
+ }
+
+ protected:
+ Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
+ USHORT numTables; /* Number of tables. */
+ USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */
+ USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */
+ USHORT rangeShift; /* NumTables x 16-searchRange. */
+ TableRecord tables[VAR]; /* TableRecord entries. numTables items */
+ public:
+ DEFINE_SIZE_ARRAY (12, tables);
+} OpenTypeFontFace;
+
+
+/*
+ * TrueType Collections
+ */
+
+struct TTCHeaderVersion1
+{
+ friend struct TTCHeader;
+
+ inline unsigned int get_face_count (void) const { return table.len; }
+ inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (table.sanitize (c, this));
+ }
+
+ protected:
+ Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
+ FixedVersion version; /* Version of the TTC Header (1.0),
+ * 0x00010000 */
+ LongOffsetLongArrayOf<OffsetTable>
+ table; /* Array of offsets to the OffsetTable for each font
+ * from the beginning of the file */
+ public:
+ DEFINE_SIZE_ARRAY (12, table);
+};
+
+struct TTCHeader
+{
+ friend struct OpenTypeFontFile;
+
+ private:
+
+ inline unsigned int get_face_count (void) const
+ {
+ switch (u.header.version.major) {
+ case 2: /* version 2 is compatible with version 1 */
+ case 1: return u.version1.get_face_count ();
+ default:return 0;
+ }
+ }
+ inline const OpenTypeFontFace& get_face (unsigned int i) const
+ {
+ switch (u.header.version.major) {
+ case 2: /* version 2 is compatible with version 1 */
+ case 1: return u.version1.get_face (i);
+ default:return Null(OpenTypeFontFace);
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
+ switch (u.header.version.major) {
+ case 2: /* version 2 is compatible with version 1 */
+ case 1: return TRACE_RETURN (u.version1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ struct {
+ Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
+ FixedVersion version; /* Version of the TTC Header (1.0 or 2.0),
+ * 0x00010000 or 0x00020000 */
+ } header;
+ TTCHeaderVersion1 version1;
+ } u;
+};
+
+
+/*
+ * OpenType Font File
+ */
+
+struct OpenTypeFontFile
+{
+ static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
+ static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
+ static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); /* TrueType Collection */
+ static const hb_tag_t TrueTag = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
+ static const hb_tag_t Typ1Tag = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
+
+ inline hb_tag_t get_tag (void) const { return u.tag; }
+
+ inline unsigned int get_face_count (void) const
+ {
+ switch (u.tag) {
+ case CFFTag: /* All the non-collection tags */
+ case TrueTag:
+ case Typ1Tag:
+ case TrueTypeTag: return 1;
+ case TTCTag: return u.ttcHeader.get_face_count ();
+ default: return 0;
+ }
+ }
+ inline const OpenTypeFontFace& get_face (unsigned int i) const
+ {
+ switch (u.tag) {
+ /* Note: for non-collection SFNT data we ignore index. This is because
+ * Apple dfont container is a container of SFNT's. So each SFNT is a
+ * non-TTC, but the index is more than zero. */
+ case CFFTag: /* All the non-collection tags */
+ case TrueTag:
+ case Typ1Tag:
+ case TrueTypeTag: return u.fontFace;
+ case TTCTag: return u.ttcHeader.get_face (i);
+ default: return Null(OpenTypeFontFace);
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
+ switch (u.tag) {
+ case CFFTag: /* All the non-collection tags */
+ case TrueTag:
+ case Typ1Tag:
+ case TrueTypeTag: return TRACE_RETURN (u.fontFace.sanitize (c));
+ case TTCTag: return TRACE_RETURN (u.ttcHeader.sanitize (c));
+ default: return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ Tag tag; /* 4-byte identifier. */
+ OpenTypeFontFace fontFace;
+ TTCHeader ttcHeader;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (4, tag);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OPEN_FILE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
new file mode 100644
index 0000000000..ee3a21dc3b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
@@ -0,0 +1,981 @@
+/*
+ * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OPEN_TYPE_PRIVATE_HH
+#define HB_OPEN_TYPE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-blob.h"
+
+
+namespace OT {
+
+
+
+/*
+ * Casts
+ */
+
+/* Cast to struct T, reference to reference */
+template<typename Type, typename TObject>
+inline const Type& CastR(const TObject &X)
+{ return reinterpret_cast<const Type&> (X); }
+template<typename Type, typename TObject>
+inline Type& CastR(TObject &X)
+{ return reinterpret_cast<Type&> (X); }
+
+/* Cast to struct T, pointer to pointer */
+template<typename Type, typename TObject>
+inline const Type* CastP(const TObject *X)
+{ return reinterpret_cast<const Type*> (X); }
+template<typename Type, typename TObject>
+inline Type* CastP(TObject *X)
+{ return reinterpret_cast<Type*> (X); }
+
+/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
+ * location pointed to by P plus Ofs bytes. */
+template<typename Type>
+inline const Type& StructAtOffset(const void *P, unsigned int offset)
+{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
+template<typename Type>
+inline Type& StructAtOffset(void *P, unsigned int offset)
+{ return * reinterpret_cast<Type*> ((char *) P + offset); }
+
+/* StructAfter<T>(X) returns the struct T& that is placed after X.
+ * Works with X of variable size also. X must implement get_size() */
+template<typename Type, typename TObject>
+inline const Type& StructAfter(const TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+template<typename Type, typename TObject>
+inline Type& StructAfter(TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+
+
+
+/*
+ * Size checking
+ */
+
+/* Check _assertion in a method environment */
+#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
+ inline void _instance_assertion_on_line_##_line (void) const \
+ { \
+ ASSERT_STATIC (_assertion); \
+ ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
+ }
+# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
+# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
+
+/* Check that _code compiles in a method environment */
+#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
+ inline void _compiles_assertion_on_line_##_line (void) const \
+ { _code; }
+# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
+# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
+
+
+#define DEFINE_SIZE_STATIC(size) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
+ static const unsigned int static_size = (size); \
+ static const unsigned int min_size = (size)
+
+/* Size signifying variable-sized array */
+#define VAR 1
+
+#define DEFINE_SIZE_UNION(size, _member) \
+ DEFINE_INSTANCE_ASSERTION (this->u._member.static_size == (size)); \
+ static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_MIN(size) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
+ static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_ARRAY(size, array) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
+ DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
+ static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_ARRAY2(size, array1, array2) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
+ DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
+ static const unsigned int min_size = (size)
+
+
+
+/*
+ * Null objects
+ */
+
+/* Global nul-content Null pool. Enlarge as necessary. */
+/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
+static const void *_NullPool[64 / sizeof (void *)];
+
+/* Generic nul-content Null objects. */
+template <typename Type>
+static inline const Type& Null (void) {
+ ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool));
+ return *CastP<Type> (_NullPool);
+}
+
+/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
+#define DEFINE_NULL_DATA(Type, data) \
+static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
+template <> \
+inline const Type& Null<Type> (void) { \
+ return *CastP<Type> (_Null##Type); \
+} /* The following line really exists such that we end in a place needing semicolon */ \
+ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
+
+/* Accessor macro. */
+#define Null(Type) Null<Type>()
+
+
+
+/*
+ * Sanitize
+ */
+
+#ifndef HB_DEBUG_SANITIZE
+#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
+#endif
+
+
+#define TRACE_SANITIZE(this) \
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
+
+/* This limits sanitizing time on really broken fonts. */
+#ifndef HB_SANITIZE_MAX_EDITS
+#define HB_SANITIZE_MAX_EDITS 100
+#endif
+
+struct hb_sanitize_context_t
+{
+ inline const char *get_name (void) { return "SANITIZE"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
+ typedef bool return_t;
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
+ static return_t default_return_value (void) { return true; }
+ bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; }
+
+ inline void init (hb_blob_t *b)
+ {
+ this->blob = hb_blob_reference (b);
+ this->writable = false;
+ }
+
+ inline void start_processing (void)
+ {
+ this->start = hb_blob_get_data (this->blob, NULL);
+ this->end = this->start + hb_blob_get_length (this->blob);
+ this->edit_count = 0;
+ this->debug_depth = 0;
+
+ DEBUG_MSG_LEVEL (SANITIZE, this->blob, 0, +1,
+ "start [%p..%p] (%lu bytes)",
+ this->start, this->end,
+ (unsigned long) (this->end - this->start));
+ }
+
+ inline void end_processing (void)
+ {
+ DEBUG_MSG_LEVEL (SANITIZE, this->blob, 0, -1,
+ "end [%p..%p] %u edit requests",
+ this->start, this->end, this->edit_count);
+
+ hb_blob_destroy (this->blob);
+ this->blob = NULL;
+ this->start = this->end = NULL;
+ }
+
+ inline bool check_range (const void *base, unsigned int len) const
+ {
+ const char *p = (const char *) base;
+
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
+ (&this->debug_depth, "SANITIZE", this->blob, NULL,
+ "check_range [%p..%p] (%d bytes) in [%p..%p]",
+ p, p + len, len,
+ this->start, this->end);
+
+ return TRACE_RETURN (likely (this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len));
+ }
+
+ inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
+ {
+ const char *p = (const char *) base;
+ bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
+
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
+ (&this->debug_depth, "SANITIZE", this->blob, NULL,
+ "check_array [%p..%p] (%d*%d=%ld bytes) in [%p..%p]",
+ p, p + (record_size * len), record_size, len, (unsigned long) record_size * len,
+ this->start, this->end);
+
+ return TRACE_RETURN (likely (!overflows && this->check_range (base, record_size * len)));
+ }
+
+ template <typename Type>
+ inline bool check_struct (const Type *obj) const
+ {
+ return likely (this->check_range (obj, obj->min_size));
+ }
+
+ inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
+ {
+ if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
+ return false;
+
+ const char *p = (const char *) base;
+ this->edit_count++;
+
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
+ (&this->debug_depth, "SANITIZE", this->blob, NULL,
+ "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
+ this->edit_count,
+ p, p + len, len,
+ this->start, this->end,
+ this->writable ? "GRANTED" : "DENIED");
+
+ return TRACE_RETURN (this->writable);
+ }
+
+ mutable unsigned int debug_depth;
+ const char *start, *end;
+ bool writable;
+ unsigned int edit_count;
+ hb_blob_t *blob;
+};
+
+
+
+/* Template to sanitize an object. */
+template <typename Type>
+struct Sanitizer
+{
+ static hb_blob_t *sanitize (hb_blob_t *blob) {
+ hb_sanitize_context_t c[1] = {{0}};
+ bool sane;
+
+ /* TODO is_sane() stuff */
+
+ c->init (blob);
+
+ retry:
+ DEBUG_MSG_FUNC (SANITIZE, blob, "start");
+
+ c->start_processing ();
+
+ if (unlikely (!c->start)) {
+ c->end_processing ();
+ return blob;
+ }
+
+ Type *t = CastP<Type> (const_cast<char *> (c->start));
+
+ sane = t->sanitize (c);
+ if (sane) {
+ if (c->edit_count) {
+ DEBUG_MSG_FUNC (SANITIZE, blob, "passed first round with %d edits; going for second round", c->edit_count);
+
+ /* sanitize again to ensure no toe-stepping */
+ c->edit_count = 0;
+ sane = t->sanitize (c);
+ if (c->edit_count) {
+ DEBUG_MSG_FUNC (SANITIZE, blob, "requested %d edits in second round; FAILLING", c->edit_count);
+ sane = false;
+ }
+ }
+ } else {
+ unsigned int edit_count = c->edit_count;
+ if (edit_count && !c->writable) {
+ c->start = hb_blob_get_data_writable (blob, NULL);
+ c->end = c->start + hb_blob_get_length (blob);
+
+ if (c->start) {
+ c->writable = true;
+ /* ok, we made it writable by relocating. try again */
+ DEBUG_MSG_FUNC (SANITIZE, blob, "retry");
+ goto retry;
+ }
+ }
+ }
+
+ c->end_processing ();
+
+ DEBUG_MSG_FUNC (SANITIZE, blob, sane ? "PASSED" : "FAILED");
+ if (sane)
+ return blob;
+ else {
+ hb_blob_destroy (blob);
+ return hb_blob_get_empty ();
+ }
+ }
+
+ static const Type* lock_instance (hb_blob_t *blob) {
+ hb_blob_make_immutable (blob);
+ const char *base = hb_blob_get_data (blob, NULL);
+ return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
+ }
+};
+
+
+
+/*
+ * Serialize
+ */
+
+#ifndef HB_DEBUG_SERIALIZE
+#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
+#endif
+
+
+#define TRACE_SERIALIZE(this) \
+ hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
+ (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
+ "");
+
+
+struct hb_serialize_context_t
+{
+ inline hb_serialize_context_t (void *start, unsigned int size)
+ {
+ this->start = (char *) start;
+ this->end = this->start + size;
+
+ this->ran_out_of_room = false;
+ this->head = this->start;
+ this->debug_depth = 0;
+ }
+
+ template <typename Type>
+ inline Type *start_serialize (void)
+ {
+ DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
+ "start [%p..%p] (%lu bytes)",
+ this->start, this->end,
+ (unsigned long) (this->end - this->start));
+
+ return start_embed<Type> ();
+ }
+
+ inline void end_serialize (void)
+ {
+ DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
+ "end [%p..%p] serialized %d bytes; %s",
+ this->start, this->end,
+ (int) (this->head - this->start),
+ this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
+
+ }
+
+ template <typename Type>
+ inline Type *copy (void)
+ {
+ assert (!this->ran_out_of_room);
+ unsigned int len = this->head - this->start;
+ void *p = malloc (len);
+ if (p)
+ memcpy (p, this->start, len);
+ return reinterpret_cast<Type *> (p);
+ }
+
+ template <typename Type>
+ inline Type *allocate_size (unsigned int size)
+ {
+ if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
+ this->ran_out_of_room = true;
+ return NULL;
+ }
+ memset (this->head, 0, size);
+ char *ret = this->head;
+ this->head += size;
+ return reinterpret_cast<Type *> (ret);
+ }
+
+ template <typename Type>
+ inline Type *allocate_min (void)
+ {
+ return this->allocate_size<Type> (Type::min_size);
+ }
+
+ template <typename Type>
+ inline Type *start_embed (void)
+ {
+ Type *ret = reinterpret_cast<Type *> (this->head);
+ return ret;
+ }
+
+ template <typename Type>
+ inline Type *embed (const Type &obj)
+ {
+ unsigned int size = obj.get_size ();
+ Type *ret = this->allocate_size<Type> (size);
+ if (unlikely (!ret)) return NULL;
+ memcpy (ret, obj, size);
+ return ret;
+ }
+
+ template <typename Type>
+ inline Type *extend_min (Type &obj)
+ {
+ unsigned int size = obj.min_size;
+ assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+ return reinterpret_cast<Type *> (&obj);
+ }
+
+ template <typename Type>
+ inline Type *extend (Type &obj)
+ {
+ unsigned int size = obj.get_size ();
+ assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+ return reinterpret_cast<Type *> (&obj);
+ }
+
+ inline void truncate (void *head)
+ {
+ assert (this->start < head && head <= this->head);
+ this->head = (char *) head;
+ }
+
+ unsigned int debug_depth;
+ char *start, *end, *head;
+ bool ran_out_of_room;
+};
+
+template <typename Type>
+struct Supplier
+{
+ inline Supplier (const Type *array, unsigned int len_)
+ {
+ head = array;
+ len = len_;
+ }
+ inline const Type operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= len)) return Type ();
+ return head[i];
+ }
+
+ inline void advance (unsigned int count)
+ {
+ if (unlikely (count > len))
+ count = len;
+ len -= count;
+ head += count;
+ }
+
+ private:
+ inline Supplier (const Supplier<Type> &); /* Disallow copy */
+ inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
+
+ unsigned int len;
+ const Type *head;
+};
+
+
+
+
+/*
+ *
+ * The OpenType Font File: Data Types
+ */
+
+
+/* "The following data types are used in the OpenType font file.
+ * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */
+
+/*
+ * Int types
+ */
+
+
+template <typename Type, int Bytes> struct BEInt;
+
+template <typename Type>
+struct BEInt<Type, 2>
+{
+ public:
+ inline void set (Type i) { hb_be_uint16_put (v,i); }
+ inline operator Type (void) const { return hb_be_uint16_get (v); }
+ inline bool operator == (const BEInt<Type, 2>& o) const { return hb_be_uint16_eq (v, o.v); }
+ inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o); }
+ private: uint8_t v[2];
+};
+template <typename Type>
+struct BEInt<Type, 4>
+{
+ public:
+ inline void set (Type i) { hb_be_uint32_put (v,i); }
+ inline operator Type (void) const { return hb_be_uint32_get (v); }
+ inline bool operator == (const BEInt<Type, 4>& o) const { return hb_be_uint32_eq (v, o.v); }
+ inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o); }
+ private: uint8_t v[4];
+};
+template <typename Type>
+struct BEInt<Type, 3>
+{
+ public:
+ inline void set (Type i) { hb_be_uint24_put (v,i); }
+ inline operator Type (void) const { return hb_be_uint24_get (v); }
+ inline bool operator == (const BEInt<Type, 3>& o) const { return hb_be_uint24_eq (v, o.v); }
+ inline bool operator != (const BEInt<Type, 3>& o) const { return !(*this == o); }
+ private: uint8_t v[3];
+};
+
+/* Integer types in big-endian order and no alignment requirement */
+template <typename Type, unsigned int Size>
+struct IntType
+{
+ inline void set (Type i) { v.set (i); }
+ inline operator Type(void) const { return v; }
+ inline bool operator == (const IntType<Type,Size> &o) const { return v == o.v; }
+ inline bool operator != (const IntType<Type,Size> &o) const { return v != o.v; }
+ static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
+ inline int cmp (IntType<Type,Size> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
+ inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (likely (c->check_struct (this)));
+ }
+ protected:
+ BEInt<Type, Size> v;
+ public:
+ DEFINE_SIZE_STATIC (Size);
+};
+
+typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
+typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
+typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
+typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */
+typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
+
+/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
+typedef SHORT FWORD;
+
+/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
+typedef USHORT UFWORD;
+
+/* Date represented in number of seconds since 12:00 midnight, January 1,
+ * 1904. The value is represented as a signed 64-bit integer. */
+struct LONGDATETIME
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (likely (c->check_struct (this)));
+ }
+ private:
+ LONG major;
+ ULONG minor;
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+/* Array of four uint8s (length = 32 bits) used to identify a script, language
+ * system, feature, or baseline */
+struct Tag : ULONG
+{
+ /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
+ inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
+ inline operator char* (void) { return reinterpret_cast<char *> (&this->v); }
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+DEFINE_NULL_DATA (Tag, " ");
+
+/* Glyph index number, same as uint16 (length = 16 bits) */
+typedef USHORT GlyphID;
+
+/* Script/language-system/feature index */
+struct Index : USHORT {
+ static const unsigned int NOT_FOUND_INDEX = 0xFFFF;
+};
+DEFINE_NULL_DATA (Index, "\xff\xff");
+
+/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */
+struct Offset : USHORT
+{
+ inline bool is_null (void) const { return 0 == *this; }
+ public:
+ DEFINE_SIZE_STATIC (2);
+};
+
+/* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */
+struct LongOffset : ULONG
+{
+ inline bool is_null (void) const { return 0 == *this; }
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+
+/* CheckSum */
+struct CheckSum : ULONG
+{
+ /* This is reference implementation from the spec. */
+ static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length)
+ {
+ uint32_t Sum = 0L;
+ const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size;
+
+ while (Table < EndPtr)
+ Sum += *Table++;
+ return Sum;
+ }
+
+ /* Note: data should be 4byte aligned and have 4byte padding at the end. */
+ inline void set_for_data (const void *data, unsigned int length)
+ { set (CalcTableChecksum ((const ULONG *) data, length)); }
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+
+/*
+ * Version Numbers
+ */
+
+struct FixedVersion
+{
+ inline uint32_t to_int (void) const { return (major << 16) + minor; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ USHORT major;
+ USHORT minor;
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+
+
+/*
+ * Template subclasses of Offset and LongOffset that do the dereferencing.
+ * Use: (base+offset)
+ */
+
+template <typename OffsetType, typename Type>
+struct GenericOffsetTo : OffsetType
+{
+ inline const Type& operator () (const void *base) const
+ {
+ unsigned int offset = *this;
+ if (unlikely (!offset)) return Null(Type);
+ return StructAtOffset<Type> (base, offset);
+ }
+
+ inline Type& serialize (hb_serialize_context_t *c, void *base)
+ {
+ Type *t = c->start_embed<Type> ();
+ this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
+ return *t;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
+ unsigned int offset = *this;
+ if (unlikely (!offset)) return TRACE_RETURN (true);
+ Type &obj = StructAtOffset<Type> (base, offset);
+ return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c));
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
+ unsigned int offset = *this;
+ if (unlikely (!offset)) return TRACE_RETURN (true);
+ Type &obj = StructAtOffset<Type> (base, offset);
+ return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
+ }
+
+ inline bool try_set (hb_sanitize_context_t *c, const OffsetType &v) {
+ if (c->may_edit (this, this->static_size)) {
+ this->set (v);
+ return true;
+ }
+ return false;
+ }
+ /* Set the offset to Null */
+ inline bool neuter (hb_sanitize_context_t *c) {
+ if (c->may_edit (this, this->static_size)) {
+ this->set (0); /* 0 is Null offset */
+ return true;
+ }
+ return false;
+ }
+};
+template <typename Base, typename OffsetType, typename Type>
+inline const Type& operator + (const Base &base, const GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); }
+template <typename Base, typename OffsetType, typename Type>
+inline Type& operator + (Base &base, GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); }
+
+template <typename Type>
+struct OffsetTo : GenericOffsetTo<Offset, Type> {};
+
+template <typename Type>
+struct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {};
+
+
+/*
+ * Array Types
+ */
+
+template <typename LenType, typename Type>
+struct GenericArrayOf
+{
+ const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
+ {
+ unsigned int count = len;
+ if (unlikely (start_offset > count))
+ count = 0;
+ else
+ count -= start_offset;
+ count = MIN (count, *pcount);
+ *pcount = count;
+ return array + start_offset;
+ }
+
+ inline const Type& operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= len)) return Null(Type);
+ return array[i];
+ }
+ inline Type& operator [] (unsigned int i)
+ {
+ return array[i];
+ }
+ inline unsigned int get_size (void) const
+ { return len.static_size + len * Type::static_size; }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ unsigned int items_len)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ len.set (items_len); /* TODO(serialize) Overflow? */
+ if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<Type> &items,
+ unsigned int items_len)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < items_len; i++)
+ array[i] = items[i];
+ items.advance (items_len);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
+
+ /* Note: for structs that do not reference other structs,
+ * we do not need to call their sanitize() as we already did
+ * a bound check on the aggregate array size. We just include
+ * a small unreachable expression to make sure the structs
+ * pointed to do have a simple sanitize(), ie. they do not
+ * reference other structs via offsets.
+ */
+ (void) (false && array[0].sanitize (c));
+
+ return TRACE_RETURN (true);
+ }
+ inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!array[i].sanitize (c, base)))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!array[i].sanitize (c, base, user_data)))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ private:
+ inline bool sanitize_shallow (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len));
+ }
+
+ public:
+ LenType len;
+ Type array[VAR];
+ public:
+ DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+};
+
+/* An array with a USHORT number of elements. */
+template <typename Type>
+struct ArrayOf : GenericArrayOf<USHORT, Type> {};
+
+/* An array with a ULONG number of elements. */
+template <typename Type>
+struct LongArrayOf : GenericArrayOf<ULONG, Type> {};
+
+/* Array of Offset's */
+template <typename Type>
+struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {};
+
+/* Array of LongOffset's */
+template <typename Type>
+struct LongOffsetArrayOf : ArrayOf<LongOffsetTo<Type> > {};
+
+/* LongArray of LongOffset's */
+template <typename Type>
+struct LongOffsetLongArrayOf : LongArrayOf<LongOffsetTo<Type> > {};
+
+/* Array of offsets relative to the beginning of the array itself. */
+template <typename Type>
+struct OffsetListOf : OffsetArrayOf<Type>
+{
+ inline const Type& operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= this->len)) return Null(Type);
+ return this+this->array[i];
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, T user_data) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
+ }
+};
+
+
+/* An array with a USHORT number of elements,
+ * starting at second element. */
+template <typename Type>
+struct HeadlessArrayOf
+{
+ inline const Type& operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= len || !i)) return Null(Type);
+ return array[i-1];
+ }
+ inline unsigned int get_size (void) const
+ { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<Type> &items,
+ unsigned int items_len)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ len.set (items_len); /* TODO(serialize) Overflow? */
+ if (unlikely (!items_len)) return TRACE_RETURN (true);
+ if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < items_len - 1; i++)
+ array[i] = items[i];
+ items.advance (items_len - 1);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize_shallow (hb_sanitize_context_t *c) {
+ return c->check_struct (this)
+ && c->check_array (this, Type::static_size, len);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
+
+ /* Note: for structs that do not reference other structs,
+ * we do not need to call their sanitize() as we already did
+ * a bound check on the aggregate array size. We just include
+ * a small unreachable expression to make sure the structs
+ * pointed to do have a simple sanitize(), ie. they do not
+ * reference other structs via offsets.
+ */
+ (void) (false && array[0].sanitize (c));
+
+ return TRACE_RETURN (true);
+ }
+
+ USHORT len;
+ Type array[VAR];
+ public:
+ DEFINE_SIZE_ARRAY (sizeof (USHORT), array);
+};
+
+
+/* An array with sorted elements. Supports binary searching. */
+template <typename Type>
+struct SortedArrayOf : ArrayOf<Type> {
+
+ template <typename SearchType>
+ inline int search (const SearchType &x) const
+ {
+ /* Hand-coded bsearch here since this is in the hot inner loop. */
+ int min = 0, max = (int) this->len - 1;
+ while (min <= max)
+ {
+ int mid = (min + max) / 2;
+ int c = this->array[mid].cmp (x);
+ if (c < 0)
+ max = mid - 1;
+ else if (c > 0)
+ min = mid + 1;
+ else
+ return mid;
+ }
+ return -1;
+ }
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OPEN_TYPE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
new file mode 100644
index 0000000000..3a9451295d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2010 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_HEAD_TABLE_HH
+#define HB_OT_HEAD_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * head -- Font Header
+ */
+
+#define HB_OT_TAG_head HB_TAG('h','e','a','d')
+
+struct head
+{
+ static const hb_tag_t Tag = HB_OT_TAG_head;
+
+ inline unsigned int get_upem (void) const {
+ unsigned int upem = unitsPerEm;
+ /* If no valid head table found, assume 1000, which matches typical Type1 usage. */
+ return 16 <= upem && upem <= 16384 ? upem : 1000;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
+ }
+
+ protected:
+ FixedVersion version; /* Version of the head table--currently
+ * 0x00010000 for version 1.0. */
+ FixedVersion fontRevision; /* Set by font manufacturer. */
+ ULONG checkSumAdjustment; /* To compute: set it to 0, sum the
+ * entire font as ULONG, then store
+ * 0xB1B0AFBA - sum. */
+ ULONG magicNumber; /* Set to 0x5F0F3CF5. */
+ USHORT flags; /* Bit 0: Baseline for font at y=0;
+ * Bit 1: Left sidebearing point at x=0;
+ * Bit 2: Instructions may depend on point size;
+ * Bit 3: Force ppem to integer values for all
+ * internal scaler math; may use fractional
+ * ppem sizes if this bit is clear;
+ * Bit 4: Instructions may alter advance width
+ * (the advance widths might not scale linearly);
+
+ * Bits 5-10: These should be set according to
+ * Apple's specification. However, they are not
+ * implemented in OpenType.
+ * Bit 5: This bit should be set in fonts that are
+ * intended to e laid out vertically, and in
+ * which the glyphs have been drawn such that an
+ * x-coordinate of 0 corresponds to the desired
+ * vertical baseline.
+ * Bit 6: This bit must be set to zero.
+ * Bit 7: This bit should be set if the font
+ * requires layout for correct linguistic
+ * rendering (e.g. Arabic fonts).
+ * Bit 8: This bit should be set for a GX font
+ * which has one or more metamorphosis effects
+ * designated as happening by default.
+ * Bit 9: This bit should be set if the font
+ * contains any strong right-to-left glyphs.
+ * Bit 10: This bit should be set if the font
+ * contains Indic-style rearrangement effects.
+
+ * Bit 11: Font data is 'lossless,' as a result
+ * of having been compressed and decompressed
+ * with the Agfa MicroType Express engine.
+ * Bit 12: Font converted (produce compatible metrics)
+ * Bit 13: Font optimized for ClearType™.
+ * Note, fonts that rely on embedded bitmaps (EBDT)
+ * for rendering should not be considered optimized
+ * for ClearType, and therefore should keep this bit
+ * cleared.
+ * Bit 14: Last Resort font. If set, indicates that
+ * the glyphs encoded in the cmap subtables are simply
+ * generic symbolic representations of code point
+ * ranges and don’t truly represent support for those
+ * code points. If unset, indicates that the glyphs
+ * encoded in the cmap subtables represent proper
+ * support for those code points.
+ * Bit 15: Reserved, set to 0. */
+ USHORT unitsPerEm; /* Valid range is from 16 to 16384. This value
+ * should be a power of 2 for fonts that have
+ * TrueType outlines. */
+ LONGDATETIME created; /* Number of seconds since 12:00 midnight,
+ January 1, 1904. 64-bit integer */
+ LONGDATETIME modified; /* Number of seconds since 12:00 midnight,
+ January 1, 1904. 64-bit integer */
+ SHORT xMin; /* For all glyph bounding boxes. */
+ SHORT yMin; /* For all glyph bounding boxes. */
+ SHORT xMax; /* For all glyph bounding boxes. */
+ SHORT yMax; /* For all glyph bounding boxes. */
+ USHORT macStyle; /* Bit 0: Bold (if set to 1);
+ * Bit 1: Italic (if set to 1)
+ * Bit 2: Underline (if set to 1)
+ * Bit 3: Outline (if set to 1)
+ * Bit 4: Shadow (if set to 1)
+ * Bit 5: Condensed (if set to 1)
+ * Bit 6: Extended (if set to 1)
+ * Bits 7-15: Reserved (set to 0). */
+ USHORT lowestRecPPEM; /* Smallest readable size in pixels. */
+ SHORT fontDirectionHint; /* Deprecated (Set to 2).
+ * 0: Fully mixed directional glyphs;
+ * 1: Only strongly left to right;
+ * 2: Like 1 but also contains neutrals;
+ * -1: Only strongly right to left;
+ * -2: Like -1 but also contains neutrals. */
+ SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */
+ SHORT glyphDataFormat; /* 0 for current format. */
+ public:
+ DEFINE_SIZE_STATIC (54);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_HEAD_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
new file mode 100644
index 0000000000..2b89c4e020
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_HHEA_TABLE_HH
+#define HB_OT_HHEA_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * hhea -- The Horizontal Header Table
+ */
+
+#define HB_OT_TAG_hhea HB_TAG('h','h','e','a')
+
+
+struct hhea
+{
+ static const hb_tag_t Tag = HB_OT_TAG_hhea;
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
+ }
+
+ protected:
+ FixedVersion version; /* 0x00010000 for version 1.0. */
+ FWORD ascender; /* Typographic ascent. <a
+ * href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
+ * (Distance from baseline of highest
+ * ascender)</a> */
+ FWORD descender; /* Typographic descent. <a
+ * href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
+ * (Distance from baseline of lowest
+ * descender)</a> */
+ FWORD lineGap; /* Typographic line gap. Negative
+ * LineGap values are treated as zero
+ * in Windows 3.1, System 6, and
+ * System 7. */
+ UFWORD advanceWidthMax; /* Maximum advance width value in
+ * 'hmtx' table. */
+ FWORD minLeftSideBearing; /* Minimum left sidebearing value in
+ * 'hmtx' table. */
+ FWORD minRightSideBearing; /* Minimum right sidebearing value;
+ * calculated as Min(aw - lsb -
+ * (xMax - xMin)). */
+ FWORD xMaxExtent; /* Max(lsb + (xMax - xMin)). */
+ SHORT caretSlopeRise; /* Used to calculate the slope of the
+ * cursor (rise/run); 1 for vertical. */
+ SHORT caretSlopeRun; /* 0 for vertical. */
+ SHORT caretOffset; /* The amount by which a slanted
+ * highlight on a glyph needs
+ * to be shifted to produce the
+ * best appearance. Set to 0 for
+ * non--slanted fonts */
+ SHORT reserved1; /* set to 0 */
+ SHORT reserved2; /* set to 0 */
+ SHORT reserved3; /* set to 0 */
+ SHORT reserved4; /* set to 0 */
+ SHORT metricDataFormat; /* 0 for current format. */
+ USHORT numberOfHMetrics; /* Number of hMetric entries in 'hmtx'
+ * table */
+ public:
+ DEFINE_SIZE_STATIC (36);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_HHEA_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
new file mode 100644
index 0000000000..b94337d0be
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_HMTX_TABLE_HH
+#define HB_OT_HMTX_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * hmtx -- The Horizontal Metrics Table
+ */
+
+#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
+
+
+struct LongHorMetric
+{
+ USHORT advanceWidth;
+ SHORT lsb;
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct hmtx
+{
+ static const hb_tag_t Tag = HB_OT_TAG_hmtx;
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ /* We don't check for anything specific here. The users of the
+ * struct do all the hard work... */
+ return TRACE_RETURN (true);
+ }
+
+ protected:
+ LongHorMetric longHorMetric[VAR]; /* Paired advance width and left side
+ * bearing values for each glyph. The
+ * value numOfHMetrics comes from
+ * the 'hhea' table. If the font is
+ * monospaced, only one entry need
+ * be in the array, but that entry is
+ * required. The last entry applies to
+ * all subsequent glyphs. */
+ SHORT leftSideBearingX[VAR]; /* Here the advanceWidth is assumed
+ * to be the same as the advanceWidth
+ * for the last entry above. The
+ * number of entries in this array is
+ * derived from numGlyphs (from 'maxp'
+ * table) minus numberOfHMetrics. This
+ * generally is used with a run of
+ * monospaced glyphs (e.g., Kanji
+ * fonts or Courier fonts). Only one
+ * run is allowed and it must be at
+ * the end. This allows a monospaced
+ * font to vary the left side bearing
+ * values for each glyph. */
+ public:
+ DEFINE_SIZE_ARRAY2 (0, longHorMetric, leftSideBearingX);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_HMTX_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
new file mode 100644
index 0000000000..2f6e80468e
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
@@ -0,0 +1,1170 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH
+#define HB_OT_LAYOUT_COMMON_PRIVATE_HH
+
+#include "hb-ot-layout-private.hh"
+#include "hb-open-type-private.hh"
+#include "hb-set-private.hh"
+
+
+namespace OT {
+
+
+#define NOT_COVERED ((unsigned int) -1)
+#define MAX_NESTING_LEVEL 8
+
+
+
+/*
+ *
+ * OpenType Layout Common Table Formats
+ *
+ */
+
+
+/*
+ * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
+ */
+
+template <typename Type>
+struct Record
+{
+ inline int cmp (hb_tag_t a) const {
+ return tag.cmp (a);
+ }
+
+ struct sanitize_closure_t {
+ hb_tag_t tag;
+ void *list_base;
+ };
+ inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+ TRACE_SANITIZE (this);
+ const sanitize_closure_t closure = {tag, base};
+ return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure));
+ }
+
+ Tag tag; /* 4-byte Tag identifier */
+ OffsetTo<Type>
+ offset; /* Offset from beginning of object holding
+ * the Record */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+template <typename Type>
+struct RecordArrayOf : SortedArrayOf<Record<Type> > {
+ inline const Tag& get_tag (unsigned int i) const
+ {
+ /* We cheat slightly and don't define separate Null objects
+ * for Record types. Instead, we return the correct Null(Tag)
+ * here. */
+ if (unlikely (i >= this->len)) return Null(Tag);
+ return (*this)[i].tag;
+ }
+ inline unsigned int get_tags (unsigned int start_offset,
+ unsigned int *record_count /* IN/OUT */,
+ hb_tag_t *record_tags /* OUT */) const
+ {
+ if (record_count) {
+ const Record<Type> *arr = this->sub_array (start_offset, record_count);
+ unsigned int count = *record_count;
+ for (unsigned int i = 0; i < count; i++)
+ record_tags[i] = arr[i].tag;
+ }
+ return this->len;
+ }
+ inline bool find_index (hb_tag_t tag, unsigned int *index) const
+ {
+ int i = this->search (tag);
+ if (i != -1) {
+ if (index) *index = i;
+ return true;
+ } else {
+ if (index) *index = Index::NOT_FOUND_INDEX;
+ return false;
+ }
+ }
+};
+
+template <typename Type>
+struct RecordListOf : RecordArrayOf<Type>
+{
+ inline const Type& operator [] (unsigned int i) const
+ { return this+RecordArrayOf<Type>::operator [](i).offset; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this));
+ }
+};
+
+
+struct RangeRecord
+{
+ inline int cmp (hb_codepoint_t g) const {
+ return g < start ? -1 : g <= end ? 0 : +1 ;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ inline bool intersects (const hb_set_t *glyphs) const {
+ return glyphs->intersects (start, end);
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const {
+ glyphs->add_range (start, end);
+ }
+
+ GlyphID start; /* First GlyphID in the range */
+ GlyphID end; /* Last GlyphID in the range */
+ USHORT value; /* Value */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+DEFINE_NULL_DATA (RangeRecord, "\000\001");
+
+
+struct IndexArray : ArrayOf<Index>
+{
+ inline unsigned int get_indexes (unsigned int start_offset,
+ unsigned int *_count /* IN/OUT */,
+ unsigned int *_indexes /* OUT */) const
+ {
+ if (_count) {
+ const USHORT *arr = this->sub_array (start_offset, _count);
+ unsigned int count = *_count;
+ for (unsigned int i = 0; i < count; i++)
+ _indexes[i] = arr[i];
+ }
+ return this->len;
+ }
+};
+
+
+struct Script;
+struct LangSys;
+struct Feature;
+
+
+struct LangSys
+{
+ inline unsigned int get_feature_count (void) const
+ { return featureIndex.len; }
+ inline hb_tag_t get_feature_index (unsigned int i) const
+ { return featureIndex[i]; }
+ inline unsigned int get_feature_indexes (unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ unsigned int *feature_indexes /* OUT */) const
+ { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
+
+ inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; }
+ inline unsigned int get_required_feature_index (void) const
+ {
+ if (reqFeatureIndex == 0xffff)
+ return Index::NOT_FOUND_INDEX;
+ return reqFeatureIndex;;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<LangSys>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c));
+ }
+
+ Offset lookupOrder; /* = Null (reserved for an offset to a
+ * reordering table) */
+ USHORT reqFeatureIndex;/* Index of a feature required for this
+ * language system--if no required features
+ * = 0xFFFF */
+ IndexArray featureIndex; /* Array of indices into the FeatureList */
+ public:
+ DEFINE_SIZE_ARRAY (6, featureIndex);
+};
+DEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF");
+
+
+struct Script
+{
+ inline unsigned int get_lang_sys_count (void) const
+ { return langSys.len; }
+ inline const Tag& get_lang_sys_tag (unsigned int i) const
+ { return langSys.get_tag (i); }
+ inline unsigned int get_lang_sys_tags (unsigned int start_offset,
+ unsigned int *lang_sys_count /* IN/OUT */,
+ hb_tag_t *lang_sys_tags /* OUT */) const
+ { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
+ inline const LangSys& get_lang_sys (unsigned int i) const
+ {
+ if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
+ return this+langSys[i].offset;
+ }
+ inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+ { return langSys.find_index (tag, index); }
+
+ inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
+ inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<Script>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<LangSys>
+ defaultLangSys; /* Offset to DefaultLangSys table--from
+ * beginning of Script table--may be Null */
+ RecordArrayOf<LangSys>
+ langSys; /* Array of LangSysRecords--listed
+ * alphabetically by LangSysTag */
+ public:
+ DEFINE_SIZE_ARRAY (4, langSys);
+};
+
+typedef RecordListOf<Script> ScriptList;
+
+
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+struct FeatureParamsSize
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
+
+ /* This subtable has some "history", if you will. Some earlier versions of
+ * Adobe tools calculated the offset of the FeatureParams sutable from the
+ * beginning of the FeatureList table! Now, that is dealt with in the
+ * Feature implementation. But we still need to be able to tell junk from
+ * real data. Note: We don't check that the nameID actually exists.
+ *
+ * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk :
+ *
+ * Yes, it is correct that a new version of the AFDKO (version 2.0) will be
+ * coming out soon, and that the makeotf program will build a font with a
+ * 'size' feature that is correct by the specification.
+ *
+ * The specification for this feature tag is in the "OpenType Layout Tag
+ * Registry". You can see a copy of this at:
+ * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size
+ *
+ * Here is one set of rules to determine if the 'size' feature is built
+ * correctly, or as by the older versions of MakeOTF. You may be able to do
+ * better.
+ *
+ * Assume that the offset to the size feature is according to specification,
+ * and make the following value checks. If it fails, assume the the size
+ * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it.
+ * If this fails, reject the 'size' feature. The older makeOTF's calculated the
+ * offset from the beginning of the FeatureList table, rather than from the
+ * beginning of the 'size' Feature table.
+ *
+ * If "design size" == 0:
+ * fails check
+ *
+ * Else if ("subfamily identifier" == 0 and
+ * "range start" == 0 and
+ * "range end" == 0 and
+ * "range start" == 0 and
+ * "menu name ID" == 0)
+ * passes check: this is the format used when there is a design size
+ * specified, but there is no recommended size range.
+ *
+ * Else if ("design size" < "range start" or
+ * "design size" > "range end" or
+ * "range end" <= "range start" or
+ * "menu name ID" < 256 or
+ * "menu name ID" > 32767 or
+ * menu name ID is not a name ID which is actually in the name table)
+ * fails test
+ * Else
+ * passes test.
+ */
+
+ if (!designSize)
+ return TRACE_RETURN (false);
+ else if (subfamilyID == 0 &&
+ subfamilyNameID == 0 &&
+ rangeStart == 0 &&
+ rangeEnd == 0)
+ return TRACE_RETURN (true);
+ else if (designSize < rangeStart ||
+ designSize > rangeEnd ||
+ subfamilyNameID < 256 ||
+ subfamilyNameID > 32767)
+ return TRACE_RETURN (false);
+ else
+ return TRACE_RETURN (true);
+ }
+
+ USHORT designSize; /* Represents the design size in 720/inch
+ * units (decipoints). The design size entry
+ * must be non-zero. When there is a design
+ * size but no recommended size range, the
+ * rest of the array will consist of zeros. */
+ USHORT subfamilyID; /* Has no independent meaning, but serves
+ * as an identifier that associates fonts
+ * in a subfamily. All fonts which share a
+ * Preferred or Font Family name and which
+ * differ only by size range shall have the
+ * same subfamily value, and no fonts which
+ * differ in weight or style shall have the
+ * same subfamily value. If this value is
+ * zero, the remaining fields in the array
+ * will be ignored. */
+ USHORT subfamilyNameID;/* If the preceding value is non-zero, this
+ * value must be set in the range 256 - 32767
+ * (inclusive). It records the value of a
+ * field in the name table, which must
+ * contain English-language strings encoded
+ * in Windows Unicode and Macintosh Roman,
+ * and may contain additional strings
+ * localized to other scripts and languages.
+ * Each of these strings is the name an
+ * application should use, in combination
+ * with the family name, to represent the
+ * subfamily in a menu. Applications will
+ * choose the appropriate version based on
+ * their selection criteria. */
+ USHORT rangeStart; /* Large end of the recommended usage range
+ * (inclusive), stored in 720/inch units
+ * (decipoints). */
+ USHORT rangeEnd; /* Small end of the recommended usage range
+ (exclusive), stored in 720/inch units
+ * (decipoints). */
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
+struct FeatureParamsStylisticSet
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ /* Right now minorVersion is at zero. Which means, any table supports
+ * the uiNameID field. */
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ USHORT minorVersion; /* (set to 0): This corresponds to a “minor”
+ * version number. Additional data may be
+ * added to the end of this Feature Parameters
+ * table in the future. */
+
+ USHORT uiNameID; /* The 'name' table name ID that specifies a
+ * string (or strings, for multiple languages)
+ * for a user-interface label for this
+ * feature. The values of uiLabelNameId and
+ * sampleTextNameId are expected to be in the
+ * font-specific name ID range (256-32767),
+ * though that is not a requirement in this
+ * Feature Parameters specification. The
+ * user-interface label for the feature can
+ * be provided in multiple languages. An
+ * English string should be included as a
+ * fallback. The string should be kept to a
+ * minimal length to fit comfortably with
+ * different application interfaces. */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct FeatureParamsCharacterVariants
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) &&
+ characters.sanitize (c));
+ }
+
+ USHORT format; /* Format number is set to 0. */
+ USHORT featUILableNameID; /* The ‘name’ table name ID that
+ * specifies a string (or strings,
+ * for multiple languages) for a
+ * user-interface label for this
+ * feature. (May be NULL.) */
+ USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that
+ * specifies a string (or strings,
+ * for multiple languages) that an
+ * application can use for tooltip
+ * text for this feature. (May be
+ * NULL.) */
+ USHORT sampleTextNameID; /* The ‘name’ table name ID that
+ * specifies sample text that
+ * illustrates the effect of this
+ * feature. (May be NULL.) */
+ USHORT numNamedParameters; /* Number of named parameters. (May
+ * be zero.) */
+ USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID
+ * used to specify strings for
+ * user-interface labels for the
+ * feature parameters. (Must be zero
+ * if numParameters is zero.) */
+ ArrayOf<UINT24>
+ characters; /* Array of the Unicode Scalar Value
+ * of the characters for which this
+ * feature provides glyph variants.
+ * (May be zero.) */
+ public:
+ DEFINE_SIZE_ARRAY (14, characters);
+};
+
+struct FeatureParams
+{
+ inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) {
+ TRACE_SANITIZE (this);
+ if (tag == HB_TAG ('s','i','z','e'))
+ return TRACE_RETURN (u.size.sanitize (c));
+ if ((tag & 0xFFFF0000) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+ return TRACE_RETURN (u.stylisticSet.sanitize (c));
+ if ((tag & 0xFFFF0000) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+ return TRACE_RETURN (u.characterVariants.sanitize (c));
+ return TRACE_RETURN (true);
+ }
+
+ inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const
+ {
+ if (tag == HB_TAG ('s','i','z','e'))
+ return u.size;
+ return Null(FeatureParamsSize);
+ }
+
+ private:
+ union {
+ FeatureParamsSize size;
+ FeatureParamsStylisticSet stylisticSet;
+ FeatureParamsCharacterVariants characterVariants;
+ } u;
+ DEFINE_SIZE_STATIC (17);
+};
+
+struct Feature
+{
+ inline unsigned int get_lookup_count (void) const
+ { return lookupIndex.len; }
+ inline hb_tag_t get_lookup_index (unsigned int i) const
+ { return lookupIndex[i]; }
+ inline unsigned int get_lookup_indexes (unsigned int start_index,
+ unsigned int *lookup_count /* IN/OUT */,
+ unsigned int *lookup_tags /* OUT */) const
+ { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
+
+ inline const FeatureParams &get_feature_params (void) const
+ { return this+featureParams; }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<Feature>::sanitize_closure_t *closure) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
+ return TRACE_RETURN (false);
+
+ /* Some earlier versions of Adobe tools calculated the offset of the
+ * FeatureParams subtable from the beginning of the FeatureList table!
+ *
+ * If sanitizing "failed" for the FeatureParams subtable, try it with the
+ * alternative location. We would know sanitize "failed" if old value
+ * of the offset was non-zero, but it's zeroed now.
+ *
+ * Only do this for the 'size' feature, since at the time of the faulty
+ * Adobe tools, only the 'size' feature had FeatureParams defined.
+ */
+
+ Offset orig_offset = featureParams;
+ if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
+ return TRACE_RETURN (false);
+
+ if (likely (!orig_offset))
+ return TRACE_RETURN (true);
+
+ if (featureParams == 0 && closure &&
+ closure->tag == HB_TAG ('s','i','z','e') &&
+ closure->list_base && closure->list_base < this)
+ {
+ unsigned int new_offset_int = (unsigned int) orig_offset -
+ ((char *) this - (char *) closure->list_base);
+
+ Offset new_offset;
+ /* Check that it did not overflow. */
+ new_offset.set (new_offset_int);
+ if (new_offset == new_offset_int &&
+ featureParams.try_set (c, new_offset) &&
+ !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
+ return TRACE_RETURN (false);
+ }
+
+ return TRACE_RETURN (true);
+ }
+
+ OffsetTo<FeatureParams>
+ featureParams; /* Offset to Feature Parameters table (if one
+ * has been defined for the feature), relative
+ * to the beginning of the Feature Table; = Null
+ * if not required */
+ IndexArray lookupIndex; /* Array of LookupList indices */
+ public:
+ DEFINE_SIZE_ARRAY (4, lookupIndex);
+};
+
+typedef RecordListOf<Feature> FeatureList;
+
+
+struct LookupFlag : USHORT
+{
+ enum Flags {
+ RightToLeft = 0x0001u,
+ IgnoreBaseGlyphs = 0x0002u,
+ IgnoreLigatures = 0x0004u,
+ IgnoreMarks = 0x0008u,
+ IgnoreFlags = 0x000Eu,
+ UseMarkFilteringSet = 0x0010u,
+ Reserved = 0x00E0u,
+ MarkAttachmentType = 0xFF00u
+ };
+ public:
+ DEFINE_SIZE_STATIC (2);
+};
+
+struct Lookup
+{
+ inline unsigned int get_subtable_count (void) const { return subTable.len; }
+
+ inline unsigned int get_type (void) const { return lookupType; }
+
+ /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
+ * higher 16-bit is mark-filtering-set if the lookup uses one.
+ * Not to be confused with glyph_props which is very similar. */
+ inline uint32_t get_props (void) const
+ {
+ unsigned int flag = lookupFlag;
+ if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
+ {
+ const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+ flag += (markFilteringSet << 16);
+ }
+ return flag;
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ unsigned int lookup_type,
+ uint32_t lookup_props,
+ unsigned int num_subtables)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ lookupType.set (lookup_type);
+ lookupFlag.set (lookup_props & 0xFFFF);
+ if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false);
+ if (lookupFlag & LookupFlag::UseMarkFilteringSet)
+ {
+ USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+ markFilteringSet.set (lookup_props >> 16);
+ }
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ /* Real sanitize of the subtables is done by GSUB/GPOS/... */
+ if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false);
+ if (lookupFlag & LookupFlag::UseMarkFilteringSet)
+ {
+ USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+ if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false);
+ }
+ return TRACE_RETURN (true);
+ }
+
+ USHORT lookupType; /* Different enumerations for GSUB and GPOS */
+ USHORT lookupFlag; /* Lookup qualifiers */
+ ArrayOf<Offset>
+ subTable; /* Array of SubTables */
+ USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
+ * structure. This field is only present if bit
+ * UseMarkFilteringSet of lookup flags is set. */
+ public:
+ DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
+};
+
+typedef OffsetListOf<Lookup> LookupList;
+
+
+/*
+ * Coverage Table
+ */
+
+struct CoverageFormat1
+{
+ friend struct Coverage;
+
+ private:
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ int i = glyphArray.search (glyph_id);
+ ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED);
+ return i;
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ glyphArray.len.set (num_glyphs);
+ if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < num_glyphs; i++)
+ glyphArray[i] = glyphs[i];
+ glyphs.advance (num_glyphs);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (glyphArray.sanitize (c));
+ }
+
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+ return glyphs->has (glyphArray[index]);
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const {
+ unsigned int count = glyphArray.len;
+ for (unsigned int i = 0; i < count; i++)
+ glyphs->add (glyphArray[i]);
+ }
+
+ public:
+ /* Older compilers need this to be public. */
+ struct Iter {
+ inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
+ inline bool more (void) { return i < c->glyphArray.len; }
+ inline void next (void) { i++; }
+ inline uint16_t get_glyph (void) { return c->glyphArray[i]; }
+ inline uint16_t get_coverage (void) { return i; }
+
+ private:
+ const struct CoverageFormat1 *c;
+ unsigned int i;
+ };
+ private:
+
+ protected:
+ USHORT coverageFormat; /* Format identifier--format = 1 */
+ SortedArrayOf<GlyphID>
+ glyphArray; /* Array of GlyphIDs--in numerical order */
+ public:
+ DEFINE_SIZE_ARRAY (4, glyphArray);
+};
+
+struct CoverageFormat2
+{
+ friend struct Coverage;
+
+ private:
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ int i = rangeRecord.search (glyph_id);
+ if (i != -1) {
+ const RangeRecord &range = rangeRecord[i];
+ return (unsigned int) range.value + (glyph_id - range.start);
+ }
+ return NOT_COVERED;
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+
+ if (unlikely (!num_glyphs)) return TRACE_RETURN (true);
+
+ unsigned int num_ranges = 1;
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (glyphs[i - 1] + 1 != glyphs[i])
+ num_ranges++;
+ rangeRecord.len.set (num_ranges);
+ if (unlikely (!c->extend (rangeRecord))) return TRACE_RETURN (false);
+
+ unsigned int range = 0;
+ rangeRecord[range].start = glyphs[0];
+ rangeRecord[range].value.set (0);
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (glyphs[i - 1] + 1 != glyphs[i]) {
+ range++;
+ rangeRecord[range].start = glyphs[i];
+ rangeRecord[range].value.set (i);
+ rangeRecord[range].end = glyphs[i];
+ } else {
+ rangeRecord[range].end = glyphs[i];
+ }
+ glyphs.advance (num_glyphs);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (rangeRecord.sanitize (c));
+ }
+
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+ unsigned int i;
+ unsigned int count = rangeRecord.len;
+ for (i = 0; i < count; i++) {
+ const RangeRecord &range = rangeRecord[i];
+ if (range.value <= index &&
+ index < (unsigned int) range.value + (range.end - range.start) &&
+ range.intersects (glyphs))
+ return true;
+ else if (index < range.value)
+ return false;
+ }
+ return false;
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const {
+ unsigned int count = rangeRecord.len;
+ for (unsigned int i = 0; i < count; i++)
+ rangeRecord[i].add_coverage (glyphs);
+ }
+
+ public:
+ /* Older compilers need this to be public. */
+ struct Iter {
+ inline void init (const CoverageFormat2 &c_) {
+ c = &c_;
+ coverage = 0;
+ i = 0;
+ j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0;
+ }
+ inline bool more (void) { return i < c->rangeRecord.len; }
+ inline void next (void) {
+ coverage++;
+ if (j == c->rangeRecord[i].end) {
+ i++;
+ if (more ())
+ j = c->rangeRecord[i].start;
+ return;
+ }
+ j++;
+ }
+ inline uint16_t get_glyph (void) { return j; }
+ inline uint16_t get_coverage (void) { return coverage; }
+
+ private:
+ const struct CoverageFormat2 *c;
+ unsigned int i, j, coverage;
+ };
+ private:
+
+ protected:
+ USHORT coverageFormat; /* Format identifier--format = 2 */
+ SortedArrayOf<RangeRecord>
+ rangeRecord; /* Array of glyph ranges--ordered by
+ * Start GlyphID. rangeCount entries
+ * long */
+ public:
+ DEFINE_SIZE_ARRAY (4, rangeRecord);
+};
+
+struct Coverage
+{
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_coverage(glyph_id);
+ case 2: return u.format2.get_coverage(glyph_id);
+ default:return NOT_COVERED;
+ }
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ unsigned int num_ranges = 1;
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (glyphs[i - 1] + 1 != glyphs[i])
+ num_ranges++;
+ u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs));
+ case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs));
+ default:return TRACE_RETURN (false);
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ inline bool intersects (const hb_set_t *glyphs) const {
+ /* TODO speed this up */
+ Coverage::Iter iter;
+ for (iter.init (*this); iter.more (); iter.next ()) {
+ if (glyphs->has (iter.get_glyph ()))
+ return true;
+ }
+ return false;
+ }
+
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+ switch (u.format) {
+ case 1: return u.format1.intersects_coverage (glyphs, index);
+ case 2: return u.format2.intersects_coverage (glyphs, index);
+ default:return false;
+ }
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const {
+ switch (u.format) {
+ case 1: u.format1.add_coverage (glyphs); break;
+ case 2: u.format2.add_coverage (glyphs); break;
+ default: break;
+ }
+ }
+
+ struct Iter {
+ Iter (void) : format (0) {};
+ inline void init (const Coverage &c_) {
+ format = c_.u.format;
+ switch (format) {
+ case 1: u.format1.init (c_.u.format1); return;
+ case 2: u.format2.init (c_.u.format2); return;
+ default: return;
+ }
+ }
+ inline bool more (void) {
+ switch (format) {
+ case 1: return u.format1.more ();
+ case 2: return u.format2.more ();
+ default:return false;
+ }
+ }
+ inline void next (void) {
+ switch (format) {
+ case 1: u.format1.next (); break;
+ case 2: u.format2.next (); break;
+ default: break;
+ }
+ }
+ inline uint16_t get_glyph (void) {
+ switch (format) {
+ case 1: return u.format1.get_glyph ();
+ case 2: return u.format2.get_glyph ();
+ default:return 0;
+ }
+ }
+ inline uint16_t get_coverage (void) {
+ switch (format) {
+ case 1: return u.format1.get_coverage ();
+ case 2: return u.format2.get_coverage ();
+ default:return -1;
+ }
+ }
+
+ private:
+ unsigned int format;
+ union {
+ CoverageFormat1::Iter format1;
+ CoverageFormat2::Iter format2;
+ } u;
+ };
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ CoverageFormat1 format1;
+ CoverageFormat2 format2;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * Class Definition Table
+ */
+
+struct ClassDefFormat1
+{
+ friend struct ClassDef;
+
+ private:
+ inline unsigned int get_class (hb_codepoint_t glyph_id) const
+ {
+ if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len))
+ return classValue[glyph_id - startGlyph];
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c));
+ }
+
+ template <typename set_t>
+ inline void add_class (set_t *glyphs, unsigned int klass) const {
+ unsigned int count = classValue.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (classValue[i] == klass)
+ glyphs->add (startGlyph + i);
+ }
+
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+ unsigned int count = classValue.len;
+ if (klass == 0)
+ {
+ /* Match if there's any glyph that is not listed! */
+ hb_codepoint_t g = -1;
+ if (!hb_set_next (glyphs, &g))
+ return false;
+ if (g < startGlyph)
+ return true;
+ g = startGlyph + count - 1;
+ if (hb_set_next (glyphs, &g))
+ return true;
+ /* Fall through. */
+ }
+ for (unsigned int i = 0; i < count; i++)
+ if (classValue[i] == klass && glyphs->has (startGlyph + i))
+ return true;
+ return false;
+ }
+
+ protected:
+ USHORT classFormat; /* Format identifier--format = 1 */
+ GlyphID startGlyph; /* First GlyphID of the classValueArray */
+ ArrayOf<USHORT>
+ classValue; /* Array of Class Values--one per GlyphID */
+ public:
+ DEFINE_SIZE_ARRAY (6, classValue);
+};
+
+struct ClassDefFormat2
+{
+ friend struct ClassDef;
+
+ private:
+ inline unsigned int get_class (hb_codepoint_t glyph_id) const
+ {
+ int i = rangeRecord.search (glyph_id);
+ if (i != -1)
+ return rangeRecord[i].value;
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (rangeRecord.sanitize (c));
+ }
+
+ template <typename set_t>
+ inline void add_class (set_t *glyphs, unsigned int klass) const {
+ unsigned int count = rangeRecord.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (rangeRecord[i].value == klass)
+ rangeRecord[i].add_coverage (glyphs);
+ }
+
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+ unsigned int count = rangeRecord.len;
+ if (klass == 0)
+ {
+ /* Match if there's any glyph that is not listed! */
+ hb_codepoint_t g = (hb_codepoint_t) -1;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (!hb_set_next (glyphs, &g))
+ break;
+ if (g < rangeRecord[i].start)
+ return true;
+ g = rangeRecord[i].end;
+ }
+ if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g))
+ return true;
+ /* Fall through. */
+ }
+ for (unsigned int i = 0; i < count; i++)
+ if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
+ return true;
+ return false;
+ }
+
+ protected:
+ USHORT classFormat; /* Format identifier--format = 2 */
+ SortedArrayOf<RangeRecord>
+ rangeRecord; /* Array of glyph ranges--ordered by
+ * Start GlyphID */
+ public:
+ DEFINE_SIZE_ARRAY (4, rangeRecord);
+};
+
+struct ClassDef
+{
+ inline unsigned int get_class (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_class(glyph_id);
+ case 2: return u.format2.get_class(glyph_id);
+ default:return 0;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ inline void add_class (hb_set_t *glyphs, unsigned int klass) const {
+ switch (u.format) {
+ case 1: u.format1.add_class (glyphs, klass); return;
+ case 2: u.format2.add_class (glyphs, klass); return;
+ default:return;
+ }
+ }
+
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+ switch (u.format) {
+ case 1: return u.format1.intersects_class (glyphs, klass);
+ case 2: return u.format2.intersects_class (glyphs, klass);
+ default:return false;
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ ClassDefFormat1 format1;
+ ClassDefFormat2 format2;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * Device Tables
+ */
+
+struct Device
+{
+
+ inline hb_position_t get_x_delta (hb_font_t *font) const
+ { return get_delta (font->x_ppem, font->x_scale); }
+
+ inline hb_position_t get_y_delta (hb_font_t *font) const
+ { return get_delta (font->y_ppem, font->y_scale); }
+
+ inline int get_delta (unsigned int ppem, int scale) const
+ {
+ if (!ppem) return 0;
+
+ int pixels = get_delta_pixels (ppem);
+
+ if (!pixels) return 0;
+
+ return pixels * (int64_t) scale / ppem;
+ }
+
+
+ inline int get_delta_pixels (unsigned int ppem_size) const
+ {
+ unsigned int f = deltaFormat;
+ if (unlikely (f < 1 || f > 3))
+ return 0;
+
+ if (ppem_size < startSize || ppem_size > endSize)
+ return 0;
+
+ unsigned int s = ppem_size - startSize;
+
+ unsigned int byte = deltaValue[s >> (4 - f)];
+ unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
+ unsigned int mask = (0xFFFF >> (16 - (1 << f)));
+
+ int delta = bits & mask;
+
+ if ((unsigned int) delta >= ((mask + 1) >> 1))
+ delta -= mask + 1;
+
+ return delta;
+ }
+
+ inline unsigned int get_size (void) const
+ {
+ unsigned int f = deltaFormat;
+ if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size;
+ return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ()));
+ }
+
+ protected:
+ USHORT startSize; /* Smallest size to correct--in ppem */
+ USHORT endSize; /* Largest size to correct--in ppem */
+ USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3
+ * 1 Signed 2-bit value, 8 values per uint16
+ * 2 Signed 4-bit value, 4 values per uint16
+ * 3 Signed 8-bit value, 2 values per uint16
+ */
+ USHORT deltaValue[VAR]; /* Array of compressed data */
+ public:
+ DEFINE_SIZE_ARRAY (6, deltaValue);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
new file mode 100644
index 0000000000..ff2d09c51f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
@@ -0,0 +1,431 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GDEF_TABLE_HH
+#define HB_OT_LAYOUT_GDEF_TABLE_HH
+
+#include "hb-ot-layout-common-private.hh"
+
+#include "hb-font-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * Attachment List Table
+ */
+
+typedef ArrayOf<USHORT> AttachPoint; /* Array of contour point indices--in
+ * increasing numerical order */
+
+struct AttachList
+{
+ inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *point_count /* IN/OUT */,
+ unsigned int *point_array /* OUT */) const
+ {
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (index == NOT_COVERED)
+ {
+ if (point_count)
+ *point_count = 0;
+ return 0;
+ }
+
+ const AttachPoint &points = this+attachPoint[index];
+
+ if (point_count) {
+ const USHORT *array = points.sub_array (start_offset, point_count);
+ unsigned int count = *point_count;
+ for (unsigned int i = 0; i < count; i++)
+ point_array[i] = array[i];
+ }
+
+ return points.len;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table -- from
+ * beginning of AttachList table */
+ OffsetArrayOf<AttachPoint>
+ attachPoint; /* Array of AttachPoint tables
+ * in Coverage Index order */
+ public:
+ DEFINE_SIZE_ARRAY (4, attachPoint);
+};
+
+/*
+ * Ligature Caret Table
+ */
+
+struct CaretValueFormat1
+{
+ friend struct CaretValue;
+
+ private:
+ inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
+ {
+ return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ protected:
+ USHORT caretValueFormat; /* Format identifier--format = 1 */
+ SHORT coordinate; /* X or Y value, in design units */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat2
+{
+ friend struct CaretValue;
+
+ private:
+ inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+ {
+ hb_position_t x, y;
+ if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y))
+ return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
+ else
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ protected:
+ USHORT caretValueFormat; /* Format identifier--format = 2 */
+ USHORT caretValuePoint; /* Contour point index on glyph */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat3
+{
+ friend struct CaretValue;
+
+ inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
+ {
+ return HB_DIRECTION_IS_HORIZONTAL (direction) ?
+ font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font) :
+ font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this));
+ }
+
+ protected:
+ USHORT caretValueFormat; /* Format identifier--format = 3 */
+ SHORT coordinate; /* X or Y value, in design units */
+ OffsetTo<Device>
+ deviceTable; /* Offset to Device table for X or Y
+ * value--from beginning of CaretValue
+ * table */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct CaretValue
+{
+ inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_caret_value (font, direction, glyph_id);
+ case 2: return u.format2.get_caret_value (font, direction, glyph_id);
+ case 3: return u.format3.get_caret_value (font, direction, glyph_id);
+ default:return 0;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ case 3: return TRACE_RETURN (u.format3.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ CaretValueFormat1 format1;
+ CaretValueFormat2 format2;
+ CaretValueFormat3 format3;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+struct LigGlyph
+{
+ inline unsigned int get_lig_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ hb_position_t *caret_array /* OUT */) const
+ {
+ if (caret_count) {
+ const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
+ unsigned int count = *caret_count;
+ for (unsigned int i = 0; i < count; i++)
+ caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id);
+ }
+
+ return carets.len;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (carets.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<CaretValue>
+ carets; /* Offset array of CaretValue tables
+ * --from beginning of LigGlyph table
+ * --in increasing coordinate order */
+ public:
+ DEFINE_SIZE_ARRAY (2, carets);
+};
+
+struct LigCaretList
+{
+ inline unsigned int get_lig_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ hb_position_t *caret_array /* OUT */) const
+ {
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (index == NOT_COVERED)
+ {
+ if (caret_count)
+ *caret_count = 0;
+ return 0;
+ }
+ const LigGlyph &lig_glyph = this+ligGlyph[index];
+ return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of LigCaretList table */
+ OffsetArrayOf<LigGlyph>
+ ligGlyph; /* Array of LigGlyph tables
+ * in Coverage Index order */
+ public:
+ DEFINE_SIZE_ARRAY (4, ligGlyph);
+};
+
+
+struct MarkGlyphSetsFormat1
+{
+ inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+ { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ LongOffsetArrayOf<Coverage>
+ coverage; /* Array of long offsets to mark set
+ * coverage tables */
+ public:
+ DEFINE_SIZE_ARRAY (4, coverage);
+};
+
+struct MarkGlyphSets
+{
+ inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.covers (set_index, glyph_id);
+ default:return false;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ MarkGlyphSetsFormat1 format1;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * GDEF -- The Glyph Definition Table
+ */
+
+struct GDEF
+{
+ static const hb_tag_t Tag = HB_OT_TAG_GDEF;
+
+ enum GlyphClasses {
+ UnclassifiedGlyph = 0,
+ BaseGlyph = 1,
+ LigatureGlyph = 2,
+ MarkGlyph = 3,
+ ComponentGlyph = 4
+ };
+
+ inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
+ inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
+ { return (this+glyphClassDef).get_class (glyph); }
+ inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
+ { (this+glyphClassDef).add_class (glyphs, klass); }
+
+ inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
+ inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
+ { return (this+markAttachClassDef).get_class (glyph); }
+
+ inline bool has_attach_points (void) const { return attachList != 0; }
+ inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *point_count /* IN/OUT */,
+ unsigned int *point_array /* OUT */) const
+ { return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); }
+
+ inline bool has_lig_carets (void) const { return ligCaretList != 0; }
+ inline unsigned int get_lig_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ hb_position_t *caret_array /* OUT */) const
+ { return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); }
+
+ inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002 && markGlyphSetsDef[0] != 0; }
+ inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+ { return version.to_int () >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ glyphClassDef.sanitize (c, this) &&
+ attachList.sanitize (c, this) &&
+ ligCaretList.sanitize (c, this) &&
+ markAttachClassDef.sanitize (c, this) &&
+ (version.to_int () < 0x00010002 || markGlyphSetsDef[0].sanitize (c, this)));
+ }
+
+
+ /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
+ * glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
+ * Not to be confused with lookup_props which is very similar. */
+ inline unsigned int get_glyph_props (hb_codepoint_t glyph) const
+ {
+ unsigned int klass = get_glyph_class (glyph);
+
+ switch (klass) {
+ default:
+ case UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED;
+ case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+ case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+ case ComponentGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT;
+ case MarkGlyph:
+ klass = get_mark_attachment_type (glyph);
+ return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
+ }
+ }
+
+
+ protected:
+ FixedVersion version; /* Version of the GDEF table--currently
+ * 0x00010002 */
+ OffsetTo<ClassDef>
+ glyphClassDef; /* Offset to class definition table
+ * for glyph type--from beginning of
+ * GDEF header (may be Null) */
+ OffsetTo<AttachList>
+ attachList; /* Offset to list of glyphs with
+ * attachment points--from beginning
+ * of GDEF header (may be Null) */
+ OffsetTo<LigCaretList>
+ ligCaretList; /* Offset to list of positioning points
+ * for ligature carets--from beginning
+ * of GDEF header (may be Null) */
+ OffsetTo<ClassDef>
+ markAttachClassDef; /* Offset to class definition table for
+ * mark attachment type--from beginning
+ * of GDEF header (may be Null) */
+ OffsetTo<MarkGlyphSets>
+ markGlyphSetsDef[VAR]; /* Offset to the table of mark set
+ * definitions--from beginning of GDEF
+ * header (may be NULL). Introduced
+ * in version 00010002. */
+ public:
+ DEFINE_SIZE_ARRAY (12, markGlyphSetsDef);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
new file mode 100644
index 0000000000..2cf90b7b5f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
@@ -0,0 +1,1629 @@
+/*
+ * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
+ * Copyright © 2010,2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GPOS_TABLE_HH
+#define HB_OT_LAYOUT_GPOS_TABLE_HH
+
+#include "hb-ot-layout-gsubgpos-private.hh"
+
+
+namespace OT {
+
+
+/* buffer **position** var allocations */
+#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */
+#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
+
+
+/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
+
+typedef USHORT Value;
+
+typedef Value ValueRecord[VAR];
+
+struct ValueFormat : USHORT
+{
+ enum Flags {
+ xPlacement = 0x0001, /* Includes horizontal adjustment for placement */
+ yPlacement = 0x0002, /* Includes vertical adjustment for placement */
+ xAdvance = 0x0004, /* Includes horizontal adjustment for advance */
+ yAdvance = 0x0008, /* Includes vertical adjustment for advance */
+ xPlaDevice = 0x0010, /* Includes horizontal Device table for placement */
+ yPlaDevice = 0x0020, /* Includes vertical Device table for placement */
+ xAdvDevice = 0x0040, /* Includes horizontal Device table for advance */
+ yAdvDevice = 0x0080, /* Includes vertical Device table for advance */
+ ignored = 0x0F00, /* Was used in TrueType Open for MM fonts */
+ reserved = 0xF000, /* For future use */
+
+ devices = 0x00F0 /* Mask for having any Device table */
+ };
+
+/* All fields are options. Only those available advance the value pointer. */
+#if 0
+ SHORT xPlacement; /* Horizontal adjustment for
+ * placement--in design units */
+ SHORT yPlacement; /* Vertical adjustment for
+ * placement--in design units */
+ SHORT xAdvance; /* Horizontal adjustment for
+ * advance--in design units (only used
+ * for horizontal writing) */
+ SHORT yAdvance; /* Vertical adjustment for advance--in
+ * design units (only used for vertical
+ * writing) */
+ Offset xPlaDevice; /* Offset to Device table for
+ * horizontal placement--measured from
+ * beginning of PosTable (may be NULL) */
+ Offset yPlaDevice; /* Offset to Device table for vertical
+ * placement--measured from beginning
+ * of PosTable (may be NULL) */
+ Offset xAdvDevice; /* Offset to Device table for
+ * horizontal advance--measured from
+ * beginning of PosTable (may be NULL) */
+ Offset yAdvDevice; /* Offset to Device table for vertical
+ * advance--measured from beginning of
+ * PosTable (may be NULL) */
+#endif
+
+ inline unsigned int get_len (void) const
+ { return _hb_popcount32 ((unsigned int) *this); }
+ inline unsigned int get_size (void) const
+ { return get_len () * Value::static_size; }
+
+ void apply_value (hb_font_t *font,
+ hb_direction_t direction,
+ const void *base,
+ const Value *values,
+ hb_glyph_position_t &glyph_pos) const
+ {
+ unsigned int x_ppem, y_ppem;
+ unsigned int format = *this;
+ hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction);
+
+ if (!format) return;
+
+ if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++));
+ if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++));
+ if (format & xAdvance) {
+ if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values++)); else values++;
+ }
+ /* y_advance values grow downward but font-space grows upward, hence negation */
+ if (format & yAdvance) {
+ if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values++)); else values++;
+ }
+
+ if (!has_device ()) return;
+
+ x_ppem = font->x_ppem;
+ y_ppem = font->y_ppem;
+
+ if (!x_ppem && !y_ppem) return;
+
+ /* pixel -> fractional pixel */
+ if (format & xPlaDevice) {
+ if (x_ppem) glyph_pos.x_offset += (base + get_device (values++)).get_x_delta (font); else values++;
+ }
+ if (format & yPlaDevice) {
+ if (y_ppem) glyph_pos.y_offset += (base + get_device (values++)).get_y_delta (font); else values++;
+ }
+ if (format & xAdvDevice) {
+ if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
+ }
+ if (format & yAdvDevice) {
+ /* y_advance values grow downward but font-space grows upward, hence negation */
+ if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
+ }
+ }
+
+ private:
+ inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Value *values) {
+ unsigned int format = *this;
+
+ if (format & xPlacement) values++;
+ if (format & yPlacement) values++;
+ if (format & xAdvance) values++;
+ if (format & yAdvance) values++;
+
+ if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+
+ return true;
+ }
+
+ static inline OffsetTo<Device>& get_device (Value* value)
+ { return *CastP<OffsetTo<Device> > (value); }
+ static inline const OffsetTo<Device>& get_device (const Value* value)
+ { return *CastP<OffsetTo<Device> > (value); }
+
+ static inline const SHORT& get_short (const Value* value)
+ { return *CastP<SHORT> (value); }
+
+ public:
+
+ inline bool has_device (void) const {
+ unsigned int format = *this;
+ return (format & devices) != 0;
+ }
+
+ inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
+ }
+
+ inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) {
+ TRACE_SANITIZE (this);
+ unsigned int len = get_len ();
+
+ if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false);
+
+ if (!has_device ()) return TRACE_RETURN (true);
+
+ for (unsigned int i = 0; i < count; i++) {
+ if (!sanitize_value_devices (c, base, values))
+ return TRACE_RETURN (false);
+ values += len;
+ }
+
+ return TRACE_RETURN (true);
+ }
+
+ /* Just sanitize referenced Device tables. Doesn't check the values themselves. */
+ inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) {
+ TRACE_SANITIZE (this);
+
+ if (!has_device ()) return TRACE_RETURN (true);
+
+ for (unsigned int i = 0; i < count; i++) {
+ if (!sanitize_value_devices (c, base, values))
+ return TRACE_RETURN (false);
+ values += stride;
+ }
+
+ return TRACE_RETURN (true);
+ }
+};
+
+
+struct AnchorFormat1
+{
+ inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ *x = font->em_scale_x (xCoordinate);
+ *y = font->em_scale_y (yCoordinate);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ SHORT xCoordinate; /* Horizontal value--in design units */
+ SHORT yCoordinate; /* Vertical value--in design units */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct AnchorFormat2
+{
+ inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ unsigned int x_ppem = font->x_ppem;
+ unsigned int y_ppem = font->y_ppem;
+ hb_position_t cx, cy;
+ hb_bool_t ret = false;
+
+ if (x_ppem || y_ppem)
+ ret = font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
+ *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
+ *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 2 */
+ SHORT xCoordinate; /* Horizontal value--in design units */
+ SHORT yCoordinate; /* Vertical value--in design units */
+ USHORT anchorPoint; /* Index to glyph contour point */
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+struct AnchorFormat3
+{
+ inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ *x = font->em_scale_x (xCoordinate);
+ *y = font->em_scale_y (yCoordinate);
+
+ if (font->x_ppem)
+ *x += (this+xDeviceTable).get_x_delta (font);
+ if (font->y_ppem)
+ *y += (this+yDeviceTable).get_x_delta (font);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 3 */
+ SHORT xCoordinate; /* Horizontal value--in design units */
+ SHORT yCoordinate; /* Vertical value--in design units */
+ OffsetTo<Device>
+ xDeviceTable; /* Offset to Device table for X
+ * coordinate-- from beginning of
+ * Anchor table (may be NULL) */
+ OffsetTo<Device>
+ yDeviceTable; /* Offset to Device table for Y
+ * coordinate-- from beginning of
+ * Anchor table (may be NULL) */
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+struct Anchor
+{
+ inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ *x = *y = 0;
+ switch (u.format) {
+ case 1: u.format1.get_anchor (font, glyph_id, x, y); return;
+ case 2: u.format2.get_anchor (font, glyph_id, x, y); return;
+ case 3: u.format3.get_anchor (font, glyph_id, x, y); return;
+ default: return;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ case 3: return TRACE_RETURN (u.format3.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ AnchorFormat1 format1;
+ AnchorFormat2 format2;
+ AnchorFormat3 format3;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+struct AnchorMatrix
+{
+ inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const {
+ *found = false;
+ if (unlikely (row >= rows || col >= cols)) return Null(Anchor);
+ *found = !matrix[row * cols + col].is_null ();
+ return this+matrix[row * cols + col];
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) {
+ TRACE_SANITIZE (this);
+ if (!c->check_struct (this)) return TRACE_RETURN (false);
+ if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false);
+ unsigned int count = rows * cols;
+ if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (!matrix[i].sanitize (c, this)) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ USHORT rows; /* Number of rows */
+ protected:
+ OffsetTo<Anchor>
+ matrix[VAR]; /* Matrix of offsets to Anchor tables--
+ * from beginning of AnchorMatrix table */
+ public:
+ DEFINE_SIZE_ARRAY (2, matrix);
+};
+
+
+struct MarkRecord
+{
+ friend struct MarkArray;
+
+ inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base));
+ }
+
+ protected:
+ USHORT klass; /* Class defined for this mark */
+ OffsetTo<Anchor>
+ markAnchor; /* Offset to Anchor table--from
+ * beginning of MarkArray table */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage order */
+{
+ inline bool apply (hb_apply_context_t *c,
+ unsigned int mark_index, unsigned int glyph_index,
+ const AnchorMatrix &anchors, unsigned int class_count,
+ unsigned int glyph_pos) const
+ {
+ TRACE_APPLY (this);
+ const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
+ unsigned int mark_class = record.klass;
+
+ const Anchor& mark_anchor = this + record.markAnchor;
+ bool found;
+ const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
+ /* If this subtable doesn't have an anchor for this base and this class,
+ * return false such that the subsequent subtables have a chance at it. */
+ if (unlikely (!found)) return TRACE_RETURN (false);
+
+ hb_position_t mark_x, mark_y, base_x, base_y;
+
+ mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_y);
+ glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
+
+ hb_glyph_position_t &o = c->buffer->cur_pos();
+ o.x_offset = base_x - mark_x;
+ o.y_offset = base_y - mark_y;
+ o.attach_lookback() = c->buffer->idx - glyph_pos;
+
+ c->buffer->idx++;
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this));
+ }
+};
+
+
+/* Lookups */
+
+struct SinglePosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ valueFormat.apply_value (c->font, c->direction, this,
+ values, c->buffer->cur_pos());
+
+ c->buffer->idx++;
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat; /* Defines the types of data in the
+ * ValueRecord */
+ ValueRecord values; /* Defines positioning
+ * value(s)--applied to all glyphs in
+ * the Coverage table */
+ public:
+ DEFINE_SIZE_ARRAY (6, values);
+};
+
+struct SinglePosFormat2
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ if (likely (index >= valueCount)) return TRACE_RETURN (false);
+
+ valueFormat.apply_value (c->font, c->direction, this,
+ &values[index * valueFormat.get_len ()],
+ c->buffer->cur_pos());
+
+ c->buffer->idx++;
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat; /* Defines the types of data in the
+ * ValueRecord */
+ USHORT valueCount; /* Number of ValueRecords */
+ ValueRecord values; /* Array of ValueRecords--positioning
+ * values applied to glyphs */
+ public:
+ DEFINE_SIZE_ARRAY (8, values);
+};
+
+struct SinglePos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ case 2: return TRACE_RETURN (c->dispatch (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ SinglePosFormat1 format1;
+ SinglePosFormat2 format2;
+ } u;
+};
+
+
+struct PairValueRecord
+{
+ friend struct PairSet;
+
+ protected:
+ GlyphID secondGlyph; /* GlyphID of second glyph in the
+ * pair--first glyph is listed in the
+ * Coverage table */
+ ValueRecord values; /* Positioning data for the first glyph
+ * followed by for second glyph */
+ public:
+ DEFINE_SIZE_ARRAY (2, values);
+};
+
+struct PairSet
+{
+ friend struct PairPosFormat1;
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = CastP<PairValueRecord> (array);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ c->input->add (record->secondGlyph);
+ record = &StructAtOffset<PairValueRecord> (record, record_size);
+ }
+ }
+
+ inline bool apply (hb_apply_context_t *c,
+ const ValueFormat *valueFormats,
+ unsigned int pos) const
+ {
+ TRACE_APPLY (this);
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = CastP<PairValueRecord> (array);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ /* TODO bsearch */
+ if (c->buffer->info[pos].codepoint == record->secondGlyph)
+ {
+ valueFormats[0].apply_value (c->font, c->direction, this,
+ &record->values[0], c->buffer->cur_pos());
+ valueFormats[1].apply_value (c->font, c->direction, this,
+ &record->values[len1], c->buffer->pos[pos]);
+ if (len2)
+ pos++;
+ c->buffer->idx = pos;
+ return TRACE_RETURN (true);
+ }
+ record = &StructAtOffset<PairValueRecord> (record, record_size);
+ }
+
+ return TRACE_RETURN (false);
+ }
+
+ struct sanitize_closure_t {
+ void *base;
+ ValueFormat *valueFormats;
+ unsigned int len1; /* valueFormats[0].get_len() */
+ unsigned int stride; /* 1 + len1 + len2 */
+ };
+
+ inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && c->check_array (array, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false);
+
+ unsigned int count = len;
+ PairValueRecord *record = CastP<PairValueRecord> (array);
+ return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride)
+ && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
+ }
+
+ protected:
+ USHORT len; /* Number of PairValueRecords */
+ USHORT array[VAR]; /* Array of PairValueRecords--ordered
+ * by GlyphID of the second glyph */
+ public:
+ DEFINE_SIZE_ARRAY (2, array);
+};
+
+struct PairPosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ unsigned int count = pairSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+pairSet[i]).collect_glyphs (c, &valueFormat1);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
+
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ if (!skippy_iter.next ()) return TRACE_RETURN (false);
+
+ return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+
+ unsigned int len1 = valueFormat1.get_len ();
+ unsigned int len2 = valueFormat2.get_len ();
+ PairSet::sanitize_closure_t closure = {
+ this,
+ &valueFormat1,
+ len1,
+ 1 + len1 + len2
+ };
+
+ return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat1; /* Defines the types of data in
+ * ValueRecord1--for the first glyph
+ * in the pair--may be zero (0) */
+ ValueFormat valueFormat2; /* Defines the types of data in
+ * ValueRecord2--for the second glyph
+ * in the pair--may be zero (0) */
+ OffsetArrayOf<PairSet>
+ pairSet; /* Array of PairSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (10, pairSet);
+};
+
+struct PairPosFormat2
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ /* (this+coverage).add_coverage (c->input); // Don't need this. */
+
+ unsigned int count1 = class1Count;
+ const ClassDef &klass1 = this+classDef1;
+ for (unsigned int i = 0; i < count1; i++)
+ klass1.add_class (c->input, i);
+
+ unsigned int count2 = class2Count;
+ const ClassDef &klass2 = this+classDef2;
+ for (unsigned int i = 0; i < count2; i++)
+ klass2.add_class (c->input, i);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
+
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ if (!skippy_iter.next ()) return TRACE_RETURN (false);
+
+ unsigned int len1 = valueFormat1.get_len ();
+ unsigned int len2 = valueFormat2.get_len ();
+ unsigned int record_len = len1 + len2;
+
+ unsigned int klass1 = (this+classDef1).get_class (c->buffer->cur().codepoint);
+ unsigned int klass2 = (this+classDef2).get_class (c->buffer->info[skippy_iter.idx].codepoint);
+ if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false);
+
+ const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
+ valueFormat1.apply_value (c->font, c->direction, this,
+ v, c->buffer->cur_pos());
+ valueFormat2.apply_value (c->font, c->direction, this,
+ v + len1, c->buffer->pos[skippy_iter.idx]);
+
+ c->buffer->idx = skippy_iter.idx;
+ if (len2)
+ c->buffer->idx++;
+
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && coverage.sanitize (c, this)
+ && classDef1.sanitize (c, this)
+ && classDef2.sanitize (c, this))) return TRACE_RETURN (false);
+
+ unsigned int len1 = valueFormat1.get_len ();
+ unsigned int len2 = valueFormat2.get_len ();
+ unsigned int stride = len1 + len2;
+ unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
+ unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
+ return TRACE_RETURN (c->check_array (values, record_size, count) &&
+ valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
+ valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat1; /* ValueRecord definition--for the
+ * first glyph of the pair--may be zero
+ * (0) */
+ ValueFormat valueFormat2; /* ValueRecord definition--for the
+ * second glyph of the pair--may be
+ * zero (0) */
+ OffsetTo<ClassDef>
+ classDef1; /* Offset to ClassDef table--from
+ * beginning of PairPos subtable--for
+ * the first glyph of the pair */
+ OffsetTo<ClassDef>
+ classDef2; /* Offset to ClassDef table--from
+ * beginning of PairPos subtable--for
+ * the second glyph of the pair */
+ USHORT class1Count; /* Number of classes in ClassDef1
+ * table--includes Class0 */
+ USHORT class2Count; /* Number of classes in ClassDef2
+ * table--includes Class0 */
+ ValueRecord values; /* Matrix of value pairs:
+ * class1-major, class2-minor,
+ * Each entry has value1 and value2 */
+ public:
+ DEFINE_SIZE_ARRAY (16, values);
+};
+
+struct PairPos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ case 2: return TRACE_RETURN (c->dispatch (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ PairPosFormat1 format1;
+ PairPosFormat2 format2;
+ } u;
+};
+
+
+struct EntryExitRecord
+{
+ friend struct CursivePosFormat1;
+
+ inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
+ }
+
+ protected:
+ OffsetTo<Anchor>
+ entryAnchor; /* Offset to EntryAnchor table--from
+ * beginning of CursivePos
+ * subtable--may be NULL */
+ OffsetTo<Anchor>
+ exitAnchor; /* Offset to ExitAnchor table--from
+ * beginning of CursivePos
+ * subtable--may be NULL */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct CursivePosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+
+ /* We don't handle mark glyphs here. */
+ if (c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
+
+ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->cur().codepoint)];
+ if (!this_record.exitAnchor) return TRACE_RETURN (false);
+
+ if (!skippy_iter.next ()) return TRACE_RETURN (false);
+
+ const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint)];
+ if (!next_record.entryAnchor) return TRACE_RETURN (false);
+
+ unsigned int i = c->buffer->idx;
+ unsigned int j = skippy_iter.idx;
+
+ hb_position_t entry_x, entry_y, exit_x, exit_y;
+ (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
+ (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y);
+
+ hb_glyph_position_t *pos = c->buffer->pos;
+
+ hb_position_t d;
+ /* Main-direction adjustment */
+ switch (c->direction) {
+ case HB_DIRECTION_LTR:
+ pos[i].x_advance = exit_x + pos[i].x_offset;
+
+ d = entry_x + pos[j].x_offset;
+ pos[j].x_advance -= d;
+ pos[j].x_offset -= d;
+ break;
+ case HB_DIRECTION_RTL:
+ d = exit_x + pos[i].x_offset;
+ pos[i].x_advance -= d;
+ pos[i].x_offset -= d;
+
+ pos[j].x_advance = entry_x + pos[j].x_offset;
+ break;
+ case HB_DIRECTION_TTB:
+ pos[i].y_advance = exit_y + pos[i].y_offset;
+
+ d = entry_y + pos[j].y_offset;
+ pos[j].y_advance -= d;
+ pos[j].y_offset -= d;
+ break;
+ case HB_DIRECTION_BTT:
+ d = exit_y + pos[i].y_offset;
+ pos[i].y_advance -= d;
+ pos[i].y_offset -= d;
+
+ pos[j].y_advance = entry_y;
+ break;
+ case HB_DIRECTION_INVALID:
+ default:
+ break;
+ }
+
+ /* Cross-direction adjustment */
+ if (c->lookup_props & LookupFlag::RightToLeft) {
+ pos[i].cursive_chain() = j - i;
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+ pos[i].y_offset = entry_y - exit_y;
+ else
+ pos[i].x_offset = entry_x - exit_x;
+ } else {
+ pos[j].cursive_chain() = i - j;
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+ pos[j].y_offset = exit_y - entry_y;
+ else
+ pos[j].x_offset = exit_x - entry_x;
+ }
+
+ c->buffer->idx = j;
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ArrayOf<EntryExitRecord>
+ entryExitRecord; /* Array of EntryExit records--in
+ * Coverage Index order */
+ public:
+ DEFINE_SIZE_ARRAY (6, entryExitRecord);
+};
+
+struct CursivePos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ CursivePosFormat1 format1;
+ } u;
+};
+
+
+typedef AnchorMatrix BaseArray; /* base-major--
+ * in order of BaseCoverage Index--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+struct MarkBasePosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+markCoverage).add_coverage (c->input);
+ (this+baseCoverage).add_coverage (c->input);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+markCoverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ /* now we search backwards for a non-mark glyph */
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+ do {
+ if (!skippy_iter.prev ()) return TRACE_RETURN (false);
+ /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
+ if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break;
+ skippy_iter.reject ();
+ } while (1);
+
+ /* The following assertion is too strong, so we've disabled it. */
+ if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
+
+ unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint);
+ if (base_index == NOT_COVERED) return TRACE_RETURN (false);
+
+ return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) &&
+ markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ markCoverage; /* Offset to MarkCoverage table--from
+ * beginning of MarkBasePos subtable */
+ OffsetTo<Coverage>
+ baseCoverage; /* Offset to BaseCoverage table--from
+ * beginning of MarkBasePos subtable */
+ USHORT classCount; /* Number of classes defined for marks */
+ OffsetTo<MarkArray>
+ markArray; /* Offset to MarkArray table--from
+ * beginning of MarkBasePos subtable */
+ OffsetTo<BaseArray>
+ baseArray; /* Offset to BaseArray table--from
+ * beginning of MarkBasePos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkBasePos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ MarkBasePosFormat1 format1;
+ } u;
+};
+
+
+typedef AnchorMatrix LigatureAttach; /* component-major--
+ * in order of writing direction--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+typedef OffsetListOf<LigatureAttach> LigatureArray;
+ /* Array of LigatureAttach
+ * tables ordered by
+ * LigatureCoverage Index */
+
+struct MarkLigPosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+markCoverage).add_coverage (c->input);
+ (this+ligatureCoverage).add_coverage (c->input);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+markCoverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ /* now we search backwards for a non-mark glyph */
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+ if (!skippy_iter.prev ()) return TRACE_RETURN (false);
+
+ /* The following assertion is too strong, so we've disabled it. */
+ if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
+
+ unsigned int j = skippy_iter.idx;
+ unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->info[j].codepoint);
+ if (lig_index == NOT_COVERED) return TRACE_RETURN (false);
+
+ const LigatureArray& lig_array = this+ligatureArray;
+ const LigatureAttach& lig_attach = lig_array[lig_index];
+
+ /* Find component to attach to */
+ unsigned int comp_count = lig_attach.rows;
+ if (unlikely (!comp_count)) return TRACE_RETURN (false);
+
+ /* We must now check whether the ligature ID of the current mark glyph
+ * is identical to the ligature ID of the found ligature. If yes, we
+ * can directly use the component index. If not, we attach the mark
+ * glyph to the last component of the ligature. */
+ unsigned int comp_index;
+ unsigned int lig_id = get_lig_id (c->buffer->info[j]);
+ unsigned int mark_id = get_lig_id (c->buffer->cur());
+ unsigned int mark_comp = get_lig_comp (c->buffer->cur());
+ if (lig_id && lig_id == mark_id && mark_comp > 0)
+ comp_index = MIN (comp_count, get_lig_comp (c->buffer->cur())) - 1;
+ else
+ comp_index = comp_count - 1;
+
+ return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) &&
+ markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ markCoverage; /* Offset to Mark Coverage table--from
+ * beginning of MarkLigPos subtable */
+ OffsetTo<Coverage>
+ ligatureCoverage; /* Offset to Ligature Coverage
+ * table--from beginning of MarkLigPos
+ * subtable */
+ USHORT classCount; /* Number of defined mark classes */
+ OffsetTo<MarkArray>
+ markArray; /* Offset to MarkArray table--from
+ * beginning of MarkLigPos subtable */
+ OffsetTo<LigatureArray>
+ ligatureArray; /* Offset to LigatureArray table--from
+ * beginning of MarkLigPos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkLigPos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ MarkLigPosFormat1 format1;
+ } u;
+};
+
+
+typedef AnchorMatrix Mark2Array; /* mark2-major--
+ * in order of Mark2Coverage Index--,
+ * mark1-minor--
+ * ordered by class--zero-based. */
+
+struct MarkMarkPosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+mark1Coverage).add_coverage (c->input);
+ (this+mark2Coverage).add_coverage (c->input);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+mark1Coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ /* now we search backwards for a suitable mark glyph until a non-mark glyph */
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
+ if (!skippy_iter.prev ()) return TRACE_RETURN (false);
+
+ if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) { return TRACE_RETURN (false); }
+
+ unsigned int j = skippy_iter.idx;
+
+ unsigned int id1 = get_lig_id (c->buffer->cur());
+ unsigned int id2 = get_lig_id (c->buffer->info[j]);
+ unsigned int comp1 = get_lig_comp (c->buffer->cur());
+ unsigned int comp2 = get_lig_comp (c->buffer->info[j]);
+
+ if (likely (id1 == id2)) {
+ if (id1 == 0) /* Marks belonging to the same base. */
+ goto good;
+ else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
+ goto good;
+ } else {
+ /* If ligature ids don't match, it may be the case that one of the marks
+ * itself is a ligature. In which case match. */
+ if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
+ goto good;
+ }
+
+ /* Didn't match. */
+ return TRACE_RETURN (false);
+
+ good:
+ unsigned int mark2_index = (this+mark2Coverage).get_coverage (c->buffer->info[j].codepoint);
+ if (mark2_index == NOT_COVERED) return TRACE_RETURN (false);
+
+ return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) &&
+ mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this)
+ && mark2Array.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ mark1Coverage; /* Offset to Combining Mark1 Coverage
+ * table--from beginning of MarkMarkPos
+ * subtable */
+ OffsetTo<Coverage>
+ mark2Coverage; /* Offset to Combining Mark2 Coverage
+ * table--from beginning of MarkMarkPos
+ * subtable */
+ USHORT classCount; /* Number of defined mark classes */
+ OffsetTo<MarkArray>
+ mark1Array; /* Offset to Mark1Array table--from
+ * beginning of MarkMarkPos subtable */
+ OffsetTo<Mark2Array>
+ mark2Array; /* Offset to Mark2Array table--from
+ * beginning of MarkMarkPos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkMarkPos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ MarkMarkPosFormat1 format1;
+ } u;
+};
+
+
+struct ContextPos : Context {};
+
+struct ChainContextPos : ChainContext {};
+
+struct ExtensionPos : Extension<ExtensionPos>
+{
+ typedef struct PosLookupSubTable LookupSubTable;
+};
+
+
+
+/*
+ * PosLookup
+ */
+
+
+struct PosLookupSubTable
+{
+ friend struct PosLookup;
+
+ enum Type {
+ Single = 1,
+ Pair = 2,
+ Cursive = 3,
+ MarkBase = 4,
+ MarkLig = 5,
+ MarkMark = 6,
+ Context = 7,
+ ChainContext = 8,
+ Extension = 9
+ };
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+ {
+ TRACE_DISPATCH (this);
+ switch (lookup_type) {
+ case Single: return TRACE_RETURN (u.single.dispatch (c));
+ case Pair: return TRACE_RETURN (u.pair.dispatch (c));
+ case Cursive: return TRACE_RETURN (u.cursive.dispatch (c));
+ case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c));
+ case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c));
+ case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c));
+ case Context: return TRACE_RETURN (u.context.dispatch (c));
+ case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c));
+ case Extension: return TRACE_RETURN (u.extension.dispatch (c));
+ default: return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
+ TRACE_SANITIZE (this);
+ if (!u.header.sub_format.sanitize (c))
+ return TRACE_RETURN (false);
+ switch (lookup_type) {
+ case Single: return TRACE_RETURN (u.single.sanitize (c));
+ case Pair: return TRACE_RETURN (u.pair.sanitize (c));
+ case Cursive: return TRACE_RETURN (u.cursive.sanitize (c));
+ case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c));
+ case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c));
+ case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c));
+ case Context: return TRACE_RETURN (u.context.sanitize (c));
+ case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c));
+ case Extension: return TRACE_RETURN (u.extension.sanitize (c));
+ default: return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ struct {
+ USHORT sub_format;
+ } header;
+ SinglePos single;
+ PairPos pair;
+ CursivePos cursive;
+ MarkBasePos markBase;
+ MarkLigPos markLig;
+ MarkMarkPos markMark;
+ ContextPos context;
+ ChainContextPos chainContext;
+ ExtensionPos extension;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, header.sub_format);
+};
+
+
+struct PosLookup : Lookup
+{
+ inline const PosLookupSubTable& get_subtable (unsigned int i) const
+ { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
+
+ inline bool is_reverse (void) const
+ {
+ return false;
+ }
+
+ inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ return TRACE_RETURN (true);
+ }
+
+ inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->set_recurse_func (NULL);
+ return TRACE_RETURN (dispatch (c));
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const
+ {
+ hb_get_coverage_context_t c;
+ const Coverage *last = NULL;
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 0; i < count; i++) {
+ const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ());
+ if (coverage != last) {
+ coverage->add_coverage (glyphs);
+ last = coverage;
+ }
+ }
+ }
+
+ inline bool apply_once (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (dispatch (c));
+ }
+
+ static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+
+ template <typename context_t>
+ static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ unsigned int lookup_type = get_type ();
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 0; i < count; i++) {
+ typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type);
+ if (c->stop_sublookup_iteration (r))
+ return TRACE_RETURN (r);
+ }
+ return TRACE_RETURN (c->default_return_value ());
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
+ OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable);
+ return TRACE_RETURN (list.sanitize (c, this, get_type ()));
+ }
+};
+
+typedef OffsetListOf<PosLookup> PosLookupList;
+
+/*
+ * GPOS -- The Glyph Positioning Table
+ */
+
+struct GPOS : GSUBGPOS
+{
+ static const hb_tag_t Tag = HB_OT_TAG_GPOS;
+
+ inline const PosLookup& get_lookup (unsigned int i) const
+ { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
+
+ static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
+ OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
+ return TRACE_RETURN (list.sanitize (c, this));
+ }
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+
+static void
+fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
+{
+ unsigned int j = pos[i].cursive_chain();
+ if (likely (!j))
+ return;
+
+ j += i;
+
+ pos[i].cursive_chain() = 0;
+
+ fix_cursive_minor_offset (pos, j, direction);
+
+ if (HB_DIRECTION_IS_HORIZONTAL (direction))
+ pos[i].y_offset += pos[j].y_offset;
+ else
+ pos[i].x_offset += pos[j].x_offset;
+}
+
+static void
+fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
+{
+ if (likely (!(pos[i].attach_lookback())))
+ return;
+
+ unsigned int j = i - pos[i].attach_lookback();
+
+ pos[i].x_offset += pos[j].x_offset;
+ pos[i].y_offset += pos[j].y_offset;
+
+ if (HB_DIRECTION_IS_FORWARD (direction))
+ for (unsigned int k = j; k < i; k++) {
+ pos[i].x_offset -= pos[k].x_advance;
+ pos[i].y_offset -= pos[k].y_advance;
+ }
+ else
+ for (unsigned int k = j + 1; k < i + 1; k++) {
+ pos[i].x_offset += pos[k].x_advance;
+ pos[i].y_offset += pos[k].y_advance;
+ }
+}
+
+void
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+ buffer->clear_positions ();
+
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0;
+}
+
+void
+GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+ unsigned int len;
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
+ hb_direction_t direction = buffer->props.direction;
+
+ /* Handle cursive connections */
+ for (unsigned int i = 0; i < len; i++)
+ fix_cursive_minor_offset (pos, i, direction);
+
+ /* Handle attachments */
+ for (unsigned int i = 0; i < len; i++)
+ fix_mark_attachment (pos, i, direction);
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+}
+
+
+/* Out-of-class implementation for methods recursing */
+
+template <typename context_t>
+inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
+{
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
+ const PosLookup &l = gpos.get_lookup (lookup_index);
+ return l.dispatch (c);
+}
+
+inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
+{
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
+ const PosLookup &l = gpos.get_lookup (lookup_index);
+ unsigned int saved_lookup_props = c->lookup_props;
+ c->set_lookup (l);
+ bool ret = l.apply_once (c);
+ c->lookup_props = saved_lookup_props;
+ return ret;
+}
+
+
+#undef attach_lookback
+#undef cursive_chain
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
new file mode 100644
index 0000000000..6ab1a2b921
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
@@ -0,0 +1,1427 @@
+/*
+ * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
+ * Copyright © 2010,2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GSUB_TABLE_HH
+#define HB_OT_LAYOUT_GSUB_TABLE_HH
+
+#include "hb-ot-layout-gsubgpos-private.hh"
+
+
+namespace OT {
+
+
+struct SingleSubstFormat1
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ hb_codepoint_t glyph_id = iter.get_glyph ();
+ if (c->glyphs->has (glyph_id))
+ c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFF);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ hb_codepoint_t glyph_id = iter.get_glyph ();
+ c->input->add (glyph_id);
+ c->output->add ((glyph_id + deltaGlyphID) & 0xFFFF);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ /* According to the Adobe Annotated OpenType Suite, result is always
+ * limited to 16bit. */
+ glyph_id = (glyph_id + deltaGlyphID) & 0xFFFF;
+ c->replace_glyph (glyph_id);
+
+ return TRACE_RETURN (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs,
+ int delta)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+ deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ SHORT deltaGlyphID; /* Add to original GlyphID to get
+ * substitute GlyphID */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct SingleSubstFormat2
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ c->glyphs->add (substitute[iter.get_coverage ()]);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ c->input->add (iter.get_glyph ());
+ c->output->add (substitute[iter.get_coverage ()]);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ if (unlikely (index >= substitute.len)) return TRACE_RETURN (false);
+
+ glyph_id = substitute[index];
+ c->replace_glyph (glyph_id);
+
+ return TRACE_RETURN (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<GlyphID> &substitutes,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return TRACE_RETURN (false);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ ArrayOf<GlyphID>
+ substitute; /* Array of substitute
+ * GlyphIDs--ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, substitute);
+};
+
+struct SingleSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<GlyphID> &substitutes,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
+ unsigned int format = 2;
+ int delta;
+ if (num_glyphs) {
+ format = 1;
+ /* TODO(serialize) check for wrap-around */
+ delta = substitutes[0] - glyphs[0];
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (delta != substitutes[i] - glyphs[i]) {
+ format = 2;
+ break;
+ }
+ }
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs, delta));
+ case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, substitutes, num_glyphs));
+ default:return TRACE_RETURN (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ case 2: return TRACE_RETURN (c->dispatch (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ SingleSubstFormat1 format1;
+ SingleSubstFormat2 format2;
+ } u;
+};
+
+
+struct Sequence
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ /* For len==0 we don't do anything, so it's harmless. */
+ return TRACE_RETURN (substitute.len <= 1);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int count = substitute.len;
+ for (unsigned int i = 0; i < count; i++)
+ c->glyphs->add (substitute[i]);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int count = substitute.len;
+ for (unsigned int i = 0; i < count; i++)
+ c->output->add (substitute[i]);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ if (unlikely (!substitute.len)) return TRACE_RETURN (false);
+
+ unsigned int klass = c->buffer->cur().glyph_props() &
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+ unsigned int count = substitute.len;
+ if (count == 1) /* Special-case to make it in-place. */
+ {
+ c->replace_glyph (substitute.array[0]);
+ }
+ else
+ {
+ for (unsigned int i = 0; i < count; i++) {
+ set_lig_props_for_component (c->buffer->cur(), i);
+ c->output_glyph (substitute.array[i], klass);
+ }
+ c->buffer->skip_glyph ();
+ }
+
+ return TRACE_RETURN (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (substitute.sanitize (c));
+ }
+
+ protected:
+ ArrayOf<GlyphID>
+ substitute; /* String of GlyphIDs to substitute */
+ public:
+ DEFINE_SIZE_ARRAY (2, substitute);
+};
+
+struct MultipleSubstFormat1
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ /* Some tools generate MultipleSubst with each substitute having length 1!
+ * So, check them. */
+ unsigned int count = sequence.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+sequence[i]).is_inplace (c))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ (this+sequence[iter.get_coverage ()]).closure (c);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ unsigned int count = sequence.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+sequence[i]).collect_glyphs (c);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ return TRACE_RETURN ((this+sequence[index]).apply (c));
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &substitute_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &substitute_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < num_glyphs; i++)
+ if (unlikely (!sequence[i].serialize (c, this).serialize (c,
+ substitute_glyphs_list,
+ substitute_len_list[i]))) return TRACE_RETURN (false);
+ substitute_len_list.advance (num_glyphs);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ OffsetArrayOf<Sequence>
+ sequence; /* Array of Sequence tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, sequence);
+};
+
+struct MultipleSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &substitute_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &substitute_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
+ unsigned int format = 1;
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list));
+ default:return TRACE_RETURN (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ MultipleSubstFormat1 format1;
+ } u;
+};
+
+
+typedef ArrayOf<GlyphID> AlternateSet; /* Array of alternate GlyphIDs--in
+ * arbitrary order */
+
+struct AlternateSubstFormat1
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ())) {
+ const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
+ unsigned int count = alt_set.len;
+ for (unsigned int i = 0; i < count; i++)
+ c->glyphs->add (alt_set[i]);
+ }
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ c->input->add (iter.get_glyph ());
+ const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
+ unsigned int count = alt_set.len;
+ for (unsigned int i = 0; i < count; i++)
+ c->output->add (alt_set[i]);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const AlternateSet &alt_set = this+alternateSet[index];
+
+ if (unlikely (!alt_set.len)) return TRACE_RETURN (false);
+
+ hb_mask_t glyph_mask = c->buffer->cur().mask;
+ hb_mask_t lookup_mask = c->lookup_mask;
+
+ /* Note: This breaks badly if two features enabled this lookup together. */
+ unsigned int shift = _hb_ctz (lookup_mask);
+ unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
+
+ if (unlikely (alt_index > alt_set.len || alt_index == 0)) return TRACE_RETURN (false);
+
+ glyph_id = alt_set[alt_index - 1];
+
+ c->replace_glyph (glyph_id);
+
+ return TRACE_RETURN (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &alternate_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &alternate_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < num_glyphs; i++)
+ if (unlikely (!alternateSet[i].serialize (c, this).serialize (c,
+ alternate_glyphs_list,
+ alternate_len_list[i]))) return TRACE_RETURN (false);
+ alternate_len_list.advance (num_glyphs);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ OffsetArrayOf<AlternateSet>
+ alternateSet; /* Array of AlternateSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, alternateSet);
+};
+
+struct AlternateSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &alternate_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &alternate_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
+ unsigned int format = 1;
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list));
+ default:return TRACE_RETURN (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ AlternateSubstFormat1 format1;
+ } u;
+};
+
+
+struct Ligature
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int count = component.len;
+ for (unsigned int i = 1; i < count; i++)
+ if (!c->glyphs->has (component[i]))
+ return;
+ c->glyphs->add (ligGlyph);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int count = component.len;
+ for (unsigned int i = 1; i < count; i++)
+ c->input->add (component[i]);
+ c->output->add (ligGlyph);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ if (c->len != component.len)
+ return TRACE_RETURN (false);
+
+ for (unsigned int i = 1; i < c->len; i++)
+ if (likely (c->glyphs[i] != component[i]))
+ return TRACE_RETURN (false);
+
+ return TRACE_RETURN (true);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int count = component.len;
+ if (unlikely (count < 1)) return TRACE_RETURN (false);
+
+ unsigned int end_offset = 0;
+ bool is_mark_ligature = false;
+ unsigned int total_component_count = 0;
+
+ if (likely (!match_input (c, count,
+ &component[1],
+ match_glyph,
+ NULL,
+ &end_offset,
+ &is_mark_ligature,
+ &total_component_count)))
+ return TRACE_RETURN (false);
+
+ /* Deal, we are forming the ligature. */
+ c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + end_offset);
+
+ ligate_input (c,
+ count,
+ &component[1],
+ match_glyph,
+ NULL,
+ ligGlyph,
+ is_mark_ligature,
+ total_component_count);
+
+ return TRACE_RETURN (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ GlyphID ligature,
+ Supplier<GlyphID> &components, /* Starting from second */
+ unsigned int num_components /* Including first component */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ ligGlyph = ligature;
+ if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ public:
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c));
+ }
+
+ protected:
+ GlyphID ligGlyph; /* GlyphID of ligature to substitute */
+ HeadlessArrayOf<GlyphID>
+ component; /* Array of component GlyphIDs--start
+ * with the second component--ordered
+ * in writing direction */
+ public:
+ DEFINE_SIZE_ARRAY (4, component);
+};
+
+struct LigatureSet
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ (this+ligature[i]).closure (c);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ (this+ligature[i]).collect_glyphs (c);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ {
+ const Ligature &lig = this+ligature[i];
+ if (lig.would_apply (c))
+ return TRACE_RETURN (true);
+ }
+ return TRACE_RETURN (false);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ {
+ const Ligature &lig = this+ligature[i];
+ if (lig.apply (c)) return TRACE_RETURN (true);
+ }
+
+ return TRACE_RETURN (false);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &ligatures,
+ Supplier<unsigned int> &component_count_list,
+ unsigned int num_ligatures,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < num_ligatures; i++)
+ if (unlikely (!ligature[i].serialize (c, this).serialize (c,
+ ligatures[i],
+ component_list,
+ component_count_list[i]))) return TRACE_RETURN (false);
+ ligatures.advance (num_ligatures);
+ component_count_list.advance (num_ligatures);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (ligature.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<Ligature>
+ ligature; /* Array LigatureSet tables
+ * ordered by preference */
+ public:
+ DEFINE_SIZE_ARRAY (2, ligature);
+};
+
+struct LigatureSubstFormat1
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ return TRACE_RETURN (false);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ (this+ligatureSet[iter.get_coverage ()]).closure (c);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ c->input->add (iter.get_glyph ());
+ (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const LigatureSet &lig_set = this+ligatureSet[index];
+ return TRACE_RETURN (lig_set.would_apply (c));
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const LigatureSet &lig_set = this+ligatureSet[index];
+ return TRACE_RETURN (lig_set.apply (c));
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &first_glyphs,
+ Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+ unsigned int num_first_glyphs,
+ Supplier<GlyphID> &ligatures_list,
+ Supplier<unsigned int> &component_count_list,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+ if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < num_first_glyphs; i++)
+ if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c,
+ ligatures_list,
+ component_count_list,
+ ligature_per_first_glyph_count_list[i],
+ component_list))) return TRACE_RETURN (false);
+ ligature_per_first_glyph_count_list.advance (num_first_glyphs);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ OffsetArrayOf<LigatureSet>
+ ligatureSet; /* Array LigatureSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, ligatureSet);
+};
+
+struct LigatureSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &first_glyphs,
+ Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+ unsigned int num_first_glyphs,
+ Supplier<GlyphID> &ligatures_list,
+ Supplier<unsigned int> &component_count_list,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
+ unsigned int format = 1;
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
+ ligatures_list, component_count_list, component_list));
+ default:return TRACE_RETURN (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ LigatureSubstFormat1 format1;
+ } u;
+};
+
+
+struct ContextSubst : Context {};
+
+struct ChainContextSubst : ChainContext {};
+
+struct ExtensionSubst : Extension<ExtensionSubst>
+{
+ typedef struct SubstLookupSubTable LookupSubTable;
+
+ inline bool is_reverse (void) const;
+};
+
+
+struct ReverseChainSingleSubstFormat1
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ unsigned int count;
+
+ count = backtrack.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+backtrack[i]).intersects (c->glyphs))
+ return;
+
+ count = lookahead.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+lookahead[i]).intersects (c->glyphs))
+ return;
+
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ c->glyphs->add (substitute[iter.get_coverage ()]);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ unsigned int count;
+
+ (this+coverage).add_coverage (c->input);
+
+ count = backtrack.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+backtrack[i]).add_coverage (c->before);
+
+ count = lookahead.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+lookahead[i]).add_coverage (c->after);
+
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ count = substitute.len;
+ for (unsigned int i = 0; i < count; i++)
+ c->output->add (substitute[i]);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL))
+ return TRACE_RETURN (false); /* No chaining to this type */
+
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+
+ if (match_backtrack (c,
+ backtrack.len, (USHORT *) backtrack.array,
+ match_coverage, this) &&
+ match_lookahead (c,
+ lookahead.len, (USHORT *) lookahead.array,
+ match_coverage, this,
+ 1))
+ {
+ c->replace_glyph_inplace (substitute[index]);
+ c->buffer->idx--; /* Reverse! */
+ return TRACE_RETURN (true);
+ }
+
+ return TRACE_RETURN (false);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
+ return TRACE_RETURN (false);
+ OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ if (!lookahead.sanitize (c, this))
+ return TRACE_RETURN (false);
+ ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ return TRACE_RETURN (substitute.sanitize (c));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetArrayOf<Coverage>
+ backtrack; /* Array of coverage tables
+ * in backtracking sequence, in glyph
+ * sequence order */
+ OffsetArrayOf<Coverage>
+ lookaheadX; /* Array of coverage tables
+ * in lookahead sequence, in glyph
+ * sequence order */
+ ArrayOf<GlyphID>
+ substituteX; /* Array of substitute
+ * GlyphIDs--ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_MIN (10);
+};
+
+struct ReverseChainSingleSubst
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ ReverseChainSingleSubstFormat1 format1;
+ } u;
+};
+
+
+
+/*
+ * SubstLookup
+ */
+
+struct SubstLookupSubTable
+{
+ friend struct SubstLookup;
+
+ enum Type {
+ Single = 1,
+ Multiple = 2,
+ Alternate = 3,
+ Ligature = 4,
+ Context = 5,
+ ChainContext = 6,
+ Extension = 7,
+ ReverseChainSingle = 8
+ };
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+ {
+ TRACE_DISPATCH (this);
+ switch (lookup_type) {
+ case Single: return TRACE_RETURN (u.single.dispatch (c));
+ case Multiple: return TRACE_RETURN (u.multiple.dispatch (c));
+ case Alternate: return TRACE_RETURN (u.alternate.dispatch (c));
+ case Ligature: return TRACE_RETURN (u.ligature.dispatch (c));
+ case Context: return TRACE_RETURN (u.context.dispatch (c));
+ case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c));
+ case Extension: return TRACE_RETURN (u.extension.dispatch (c));
+ case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.dispatch (c));
+ default: return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
+ TRACE_SANITIZE (this);
+ if (!u.header.sub_format.sanitize (c))
+ return TRACE_RETURN (false);
+ switch (lookup_type) {
+ case Single: return TRACE_RETURN (u.single.sanitize (c));
+ case Multiple: return TRACE_RETURN (u.multiple.sanitize (c));
+ case Alternate: return TRACE_RETURN (u.alternate.sanitize (c));
+ case Ligature: return TRACE_RETURN (u.ligature.sanitize (c));
+ case Context: return TRACE_RETURN (u.context.sanitize (c));
+ case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c));
+ case Extension: return TRACE_RETURN (u.extension.sanitize (c));
+ case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.sanitize (c));
+ default: return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ struct {
+ USHORT sub_format;
+ } header;
+ SingleSubst single;
+ MultipleSubst multiple;
+ AlternateSubst alternate;
+ LigatureSubst ligature;
+ ContextSubst context;
+ ChainContextSubst chainContext;
+ ExtensionSubst extension;
+ ReverseChainSingleSubst reverseChainContextSingle;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, header.sub_format);
+};
+
+
+struct SubstLookup : Lookup
+{
+ inline const SubstLookupSubTable& get_subtable (unsigned int i) const
+ { return this+CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i]; }
+
+ inline static bool lookup_type_is_reverse (unsigned int lookup_type)
+ { return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
+
+ inline bool is_reverse (void) const
+ {
+ unsigned int type = get_type ();
+ if (unlikely (type == SubstLookupSubTable::Extension))
+ return CastR<ExtensionSubst> (get_subtable(0)).is_reverse ();
+ return lookup_type_is_reverse (type);
+ }
+
+ inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ c->set_recurse_func (dispatch_recurse_func<hb_is_inplace_context_t>);
+ return TRACE_RETURN (dispatch (c));
+ }
+
+ inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>);
+ return TRACE_RETURN (dispatch (c));
+ }
+
+ inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
+ return TRACE_RETURN (dispatch (c));
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const
+ {
+ hb_get_coverage_context_t c;
+ const Coverage *last = NULL;
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 0; i < count; i++) {
+ const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ());
+ if (coverage != last) {
+ coverage->add_coverage (glyphs);
+ last = coverage;
+ }
+ }
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const
+ {
+ TRACE_WOULD_APPLY (this);
+ if (unlikely (!c->len)) return TRACE_RETURN (false);
+ if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false);
+ return TRACE_RETURN (dispatch (c));
+ }
+
+ inline bool apply_once (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (dispatch (c));
+ }
+
+ static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+
+ inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
+ unsigned int i)
+ { return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c, this); }
+
+ inline bool serialize_single (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &glyphs,
+ Supplier<GlyphID> &substitutes,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return TRACE_RETURN (false);
+ return TRACE_RETURN (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs));
+ }
+
+ inline bool serialize_multiple (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &substitute_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &substitute_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return TRACE_RETURN (false);
+ return TRACE_RETURN (serialize_subtable (c, 0).u.multiple.serialize (c, glyphs, substitute_len_list, num_glyphs,
+ substitute_glyphs_list));
+ }
+
+ inline bool serialize_alternate (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &alternate_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &alternate_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return TRACE_RETURN (false);
+ return TRACE_RETURN (serialize_subtable (c, 0).u.alternate.serialize (c, glyphs, alternate_len_list, num_glyphs,
+ alternate_glyphs_list));
+ }
+
+ inline bool serialize_ligature (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &first_glyphs,
+ Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+ unsigned int num_first_glyphs,
+ Supplier<GlyphID> &ligatures_list,
+ Supplier<unsigned int> &component_count_list,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return TRACE_RETURN (false);
+ return TRACE_RETURN (serialize_subtable (c, 0).u.ligature.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
+ ligatures_list, component_count_list, component_list));
+ }
+
+ template <typename context_t>
+ static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ unsigned int lookup_type = get_type ();
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 0; i < count; i++) {
+ typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type);
+ if (c->stop_sublookup_iteration (r))
+ return TRACE_RETURN (r);
+ }
+ return TRACE_RETURN (c->default_return_value ());
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c)
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
+ OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable);
+ if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false);
+
+ if (unlikely (get_type () == SubstLookupSubTable::Extension))
+ {
+ /* The spec says all subtables of an Extension lookup should
+ * have the same type. This is specially important if one has
+ * a reverse type! */
+ unsigned int type = get_subtable (0).u.extension.get_type ();
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 1; i < count; i++)
+ if (get_subtable (i).u.extension.get_type () != type)
+ return TRACE_RETURN (false);
+ }
+ return TRACE_RETURN (true);
+ }
+};
+
+typedef OffsetListOf<SubstLookup> SubstLookupList;
+
+/*
+ * GSUB -- The Glyph Substitution Table
+ */
+
+struct GSUB : GSUBGPOS
+{
+ static const hb_tag_t Tag = HB_OT_TAG_GSUB;
+
+ inline const SubstLookup& get_lookup (unsigned int i) const
+ { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
+
+ static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer);
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
+ OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
+ return TRACE_RETURN (list.sanitize (c, this));
+ }
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+
+void
+GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
+ HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+
+ const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++) {
+ buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
+ buffer->info[i].glyph_props() = gdef.get_glyph_props (buffer->info[i].codepoint);
+ }
+}
+
+void
+GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
+{
+}
+
+
+/* Out-of-class implementation for methods recursing */
+
+inline bool ExtensionSubst::is_reverse (void) const
+{
+ unsigned int type = get_type ();
+ if (unlikely (type == SubstLookupSubTable::Extension))
+ return CastR<ExtensionSubst> (get_subtable<SubstLookupSubTable>()).is_reverse ();
+ return SubstLookup::lookup_type_is_reverse (type);
+}
+
+template <typename context_t>
+inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
+{
+ const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
+ const SubstLookup &l = gsub.get_lookup (lookup_index);
+ return l.dispatch (c);
+}
+
+inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
+{
+ const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
+ const SubstLookup &l = gsub.get_lookup (lookup_index);
+ unsigned int saved_lookup_props = c->lookup_props;
+ c->set_lookup (l);
+ bool ret = l.apply_once (c);
+ c->lookup_props = saved_lookup_props;
+ return ret;
+}
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GSUB_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
new file mode 100644
index 0000000000..316f506f0d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -0,0 +1,2449 @@
+/*
+ * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
+ * Copyright © 2010,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
+#define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
+
+#include "hb-buffer-private.hh"
+#include "hb-ot-layout-gdef-table.hh"
+#include "hb-set-private.hh"
+
+
+namespace OT {
+
+
+
+#define TRACE_DISPATCH(this) \
+ hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
+
+
+
+#ifndef HB_DEBUG_IS_INPLACE
+#define HB_DEBUG_IS_INPLACE (HB_DEBUG+0)
+#endif
+
+#define TRACE_IS_INPLACE(this) \
+ hb_auto_trace_t<HB_DEBUG_IS_INPLACE, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
+
+struct hb_is_inplace_context_t
+{
+ inline const char *get_name (void) { return "IS_INPLACE"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_IS_INPLACE;
+ typedef bool return_t;
+ typedef return_t (*recurse_func_t) (hb_is_inplace_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.is_inplace (this); }
+ static return_t default_return_value (void) { return true; }
+ bool stop_sublookup_iteration (return_t r) const { return !r; }
+
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ nesting_level_left--;
+ bool ret = recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return ret;
+ }
+
+ hb_face_t *face;
+ recurse_func_t recurse_func;
+ unsigned int nesting_level_left;
+ unsigned int debug_depth;
+
+ hb_is_inplace_context_t (hb_face_t *face_,
+ unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
+ face (face_),
+ recurse_func (NULL),
+ nesting_level_left (nesting_level_left_),
+ debug_depth (0) {}
+
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+
+#ifndef HB_DEBUG_CLOSURE
+#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
+#endif
+
+#define TRACE_CLOSURE(this) \
+ hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
+
+struct hb_closure_context_t
+{
+ inline const char *get_name (void) { return "CLOSURE"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
+ typedef hb_void_t return_t;
+ typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
+ static return_t default_return_value (void) { return HB_VOID; }
+ bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ nesting_level_left--;
+ recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return HB_VOID;
+ }
+
+ hb_face_t *face;
+ hb_set_t *glyphs;
+ recurse_func_t recurse_func;
+ unsigned int nesting_level_left;
+ unsigned int debug_depth;
+
+ hb_closure_context_t (hb_face_t *face_,
+ hb_set_t *glyphs_,
+ unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
+ face (face_),
+ glyphs (glyphs_),
+ recurse_func (NULL),
+ nesting_level_left (nesting_level_left_),
+ debug_depth (0) {}
+
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+
+#ifndef HB_DEBUG_WOULD_APPLY
+#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
+#endif
+
+#define TRACE_WOULD_APPLY(this) \
+ hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "%d glyphs", c->len);
+
+struct hb_would_apply_context_t
+{
+ inline const char *get_name (void) { return "WOULD_APPLY"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
+ typedef bool return_t;
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
+ static return_t default_return_value (void) { return false; }
+ bool stop_sublookup_iteration (return_t r) const { return r; }
+
+ hb_face_t *face;
+ const hb_codepoint_t *glyphs;
+ unsigned int len;
+ bool zero_context;
+ unsigned int debug_depth;
+
+ hb_would_apply_context_t (hb_face_t *face_,
+ const hb_codepoint_t *glyphs_,
+ unsigned int len_,
+ bool zero_context_) :
+ face (face_),
+ glyphs (glyphs_),
+ len (len_),
+ zero_context (zero_context_),
+ debug_depth (0) {}
+};
+
+
+
+#ifndef HB_DEBUG_COLLECT_GLYPHS
+#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
+#endif
+
+#define TRACE_COLLECT_GLYPHS(this) \
+ hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
+
+struct hb_collect_glyphs_context_t
+{
+ inline const char *get_name (void) { return "COLLECT_GLYPHS"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
+ typedef hb_void_t return_t;
+ typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
+ static return_t default_return_value (void) { return HB_VOID; }
+ bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ /* Note that GPOS sets recurse_func to NULL already, so it doesn't get
+ * past the previous check. For GSUB, we only want to collect the output
+ * glyphs in the recursion. If output is not requested, we can go home now.
+ *
+ * Note further, that the above is not exactly correct. A recursed lookup
+ * is allowed to match input that is not matched in the context, but that's
+ * not how most fonts are built. It's possible to relax that and recurse
+ * with all sets here if it proves to be an issue.
+ */
+
+ if (output == hb_set_get_empty ())
+ return HB_VOID;
+
+ hb_set_t *old_before = before;
+ hb_set_t *old_input = input;
+ hb_set_t *old_after = after;
+ before = input = after = hb_set_get_empty ();
+
+ nesting_level_left--;
+ recurse_func (this, lookup_index);
+ nesting_level_left++;
+
+ before = old_before;
+ input = old_input;
+ after = old_after;
+
+ return HB_VOID;
+ }
+
+ hb_face_t *face;
+ hb_set_t *before;
+ hb_set_t *input;
+ hb_set_t *after;
+ hb_set_t *output;
+ recurse_func_t recurse_func;
+ unsigned int nesting_level_left;
+ unsigned int debug_depth;
+
+ hb_collect_glyphs_context_t (hb_face_t *face_,
+ hb_set_t *glyphs_before, /* OUT. May be NULL */
+ hb_set_t *glyphs_input, /* OUT. May be NULL */
+ hb_set_t *glyphs_after, /* OUT. May be NULL */
+ hb_set_t *glyphs_output, /* OUT. May be NULL */
+ unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
+ face (face_),
+ before (glyphs_before ? glyphs_before : hb_set_get_empty ()),
+ input (glyphs_input ? glyphs_input : hb_set_get_empty ()),
+ after (glyphs_after ? glyphs_after : hb_set_get_empty ()),
+ output (glyphs_output ? glyphs_output : hb_set_get_empty ()),
+ recurse_func (NULL),
+ nesting_level_left (nesting_level_left_),
+ debug_depth (0) {}
+
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+
+struct hb_get_coverage_context_t
+{
+ inline const char *get_name (void) { return "GET_COVERAGE"; }
+ static const unsigned int max_debug_depth = 0;
+ typedef const Coverage &return_t;
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
+ static return_t default_return_value (void) { return Null(Coverage); }
+
+ hb_get_coverage_context_t (void) :
+ debug_depth (0) {}
+
+ unsigned int debug_depth;
+};
+
+
+
+#ifndef HB_DEBUG_APPLY
+#define HB_DEBUG_APPLY (HB_DEBUG+0)
+#endif
+
+#define TRACE_APPLY(this) \
+ hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
+
+struct hb_apply_context_t
+{
+ inline const char *get_name (void) { return "APPLY"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
+ typedef bool return_t;
+ typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.apply (this); }
+ static return_t default_return_value (void) { return false; }
+ bool stop_sublookup_iteration (return_t r) const { return r; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ nesting_level_left--;
+ bool ret = recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return ret;
+ }
+
+ unsigned int table_index; /* GSUB/GPOS */
+ hb_font_t *font;
+ hb_face_t *face;
+ hb_buffer_t *buffer;
+ hb_direction_t direction;
+ hb_mask_t lookup_mask;
+ bool auto_zwj;
+ recurse_func_t recurse_func;
+ unsigned int nesting_level_left;
+ unsigned int lookup_props;
+ const GDEF &gdef;
+ bool has_glyph_classes;
+ unsigned int debug_depth;
+
+
+ hb_apply_context_t (unsigned int table_index_,
+ hb_font_t *font_,
+ hb_buffer_t *buffer_) :
+ table_index (table_index_),
+ font (font_), face (font->face), buffer (buffer_),
+ direction (buffer_->props.direction),
+ lookup_mask (1),
+ auto_zwj (true),
+ recurse_func (NULL),
+ nesting_level_left (MAX_NESTING_LEVEL),
+ lookup_props (0),
+ gdef (*hb_ot_layout_from_face (face)->gdef),
+ has_glyph_classes (gdef.has_glyph_classes ()),
+ debug_depth (0) {}
+
+ inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
+ inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
+ inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+ inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
+ inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
+
+ struct matcher_t
+ {
+ inline matcher_t (void) :
+ lookup_props (0),
+ ignore_zwnj (false),
+ ignore_zwj (false),
+ mask (-1),
+#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
+ syllable arg1(0),
+#undef arg1
+ match_func (NULL),
+ match_data (NULL) {};
+
+ typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+
+ inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
+ inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
+ inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
+ inline void set_mask (hb_mask_t mask_) { mask = mask_; }
+ inline void set_syllable (uint8_t syllable_) { syllable = syllable_; }
+ inline void set_match_func (match_func_t match_func_,
+ const void *match_data_)
+ { match_func = match_func_; match_data = match_data_; }
+
+ enum may_match_t {
+ MATCH_NO,
+ MATCH_YES,
+ MATCH_MAYBE
+ };
+
+ inline may_match_t may_match (const hb_glyph_info_t &info,
+ const USHORT *glyph_data) const
+ {
+ if (!(info.mask & mask) ||
+ (syllable && syllable != info.syllable ()))
+ return MATCH_NO;
+
+ if (match_func)
+ return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
+
+ return MATCH_MAYBE;
+ }
+
+ enum may_skip_t {
+ SKIP_NO,
+ SKIP_YES,
+ SKIP_MAYBE
+ };
+
+ inline may_skip_t
+ may_skip (const hb_apply_context_t *c,
+ const hb_glyph_info_t &info) const
+ {
+ unsigned int property;
+
+ property = info.glyph_props();
+
+ if (!c->match_properties (info.codepoint, property, lookup_props))
+ return SKIP_YES;
+
+ if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
+ (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
+ (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
+ !is_a_ligature (info)))
+ return SKIP_MAYBE;
+
+ return SKIP_NO;
+ }
+
+ protected:
+ unsigned int lookup_props;
+ bool ignore_zwnj;
+ bool ignore_zwj;
+ hb_mask_t mask;
+ uint8_t syllable;
+ match_func_t match_func;
+ const void *match_data;
+ };
+
+ struct skipping_forward_iterator_t
+ {
+ inline skipping_forward_iterator_t (hb_apply_context_t *c_,
+ unsigned int start_index_,
+ unsigned int num_items_,
+ bool context_match = false) :
+ idx (start_index_),
+ c (c_),
+ match_glyph_data (NULL),
+ num_items (num_items_),
+ end (c->buffer->len)
+ {
+ matcher.set_lookup_props (c->lookup_props);
+ /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+ matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
+ matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
+ if (!context_match)
+ matcher.set_mask (c->lookup_mask);
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ }
+ inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
+ inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
+ inline void set_match_func (matcher_t::match_func_t match_func,
+ const void *match_data,
+ const USHORT glyph_data[])
+ {
+ matcher.set_match_func (match_func, match_data);
+ match_glyph_data = glyph_data;
+ }
+
+ inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); }
+ inline void reject (void) { num_items++; match_glyph_data--; }
+ inline bool next (void)
+ {
+ assert (num_items > 0);
+ while (!has_no_chance ())
+ {
+ idx++;
+ const hb_glyph_info_t &info = c->buffer->info[idx];
+
+ matcher_t::may_skip_t skip = matcher.may_skip (c, info);
+ if (unlikely (skip == matcher_t::SKIP_YES))
+ continue;
+
+ matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data);
+ if (match == matcher_t::MATCH_YES ||
+ (match == matcher_t::MATCH_MAYBE &&
+ skip == matcher_t::SKIP_NO))
+ {
+ num_items--;
+ match_glyph_data++;
+ return true;
+ }
+
+ if (skip == matcher_t::SKIP_NO)
+ return false;
+ }
+ return false;
+ }
+
+ unsigned int idx;
+ protected:
+ hb_apply_context_t *c;
+ matcher_t matcher;
+ const USHORT *match_glyph_data;
+
+ unsigned int num_items;
+ unsigned int end;
+ };
+
+ struct skipping_backward_iterator_t
+ {
+ inline skipping_backward_iterator_t (hb_apply_context_t *c_,
+ unsigned int start_index_,
+ unsigned int num_items_,
+ bool context_match = false) :
+ idx (start_index_),
+ c (c_),
+ match_glyph_data (NULL),
+ num_items (num_items_)
+ {
+ matcher.set_lookup_props (c->lookup_props);
+ /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+ matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
+ matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
+ if (!context_match)
+ matcher.set_mask (c->lookup_mask);
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ }
+ inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
+ inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
+ inline void set_match_func (matcher_t::match_func_t match_func,
+ const void *match_data,
+ const USHORT glyph_data[])
+ {
+ matcher.set_match_func (match_func, match_data);
+ match_glyph_data = glyph_data;
+ }
+
+ inline bool has_no_chance (void) const { return unlikely (idx < num_items); }
+ inline void reject (void) { num_items++; }
+ inline bool prev (void)
+ {
+ assert (num_items > 0);
+ while (!has_no_chance ())
+ {
+ idx--;
+ const hb_glyph_info_t &info = c->buffer->out_info[idx];
+
+ matcher_t::may_skip_t skip = matcher.may_skip (c, info);
+
+ if (unlikely (skip == matcher_t::SKIP_YES))
+ continue;
+
+ matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data);
+ if (match == matcher_t::MATCH_YES ||
+ (match == matcher_t::MATCH_MAYBE &&
+ skip == matcher_t::SKIP_NO))
+ {
+ num_items--;
+ match_glyph_data++;
+ return true;
+ }
+
+ if (skip == matcher_t::SKIP_NO)
+ return false;
+ }
+ return false;
+ }
+
+ unsigned int idx;
+ protected:
+ hb_apply_context_t *c;
+ matcher_t matcher;
+ const USHORT *match_glyph_data;
+
+ unsigned int num_items;
+ };
+
+ inline bool
+ match_properties_mark (hb_codepoint_t glyph,
+ unsigned int glyph_props,
+ unsigned int lookup_props) const
+ {
+ /* If using mark filtering sets, the high short of
+ * lookup_props has the set index.
+ */
+ if (lookup_props & LookupFlag::UseMarkFilteringSet)
+ return gdef.mark_set_covers (lookup_props >> 16, glyph);
+
+ /* The second byte of lookup_props has the meaning
+ * "ignore marks of attachment type different than
+ * the attachment type specified."
+ */
+ if (lookup_props & LookupFlag::MarkAttachmentType)
+ return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
+
+ return true;
+ }
+
+ inline bool
+ match_properties (hb_codepoint_t glyph,
+ unsigned int glyph_props,
+ unsigned int lookup_props) const
+ {
+ /* Not covered, if, for example, glyph class is ligature and
+ * lookup_props includes LookupFlags::IgnoreLigatures
+ */
+ if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
+ return false;
+
+ if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+ return match_properties_mark (glyph, glyph_props, lookup_props);
+
+ return true;
+ }
+
+ inline bool
+ check_glyph_property (hb_glyph_info_t *info,
+ unsigned int lookup_props) const
+ {
+ unsigned int property;
+
+ property = info->glyph_props();
+
+ return match_properties (info->codepoint, property, lookup_props);
+ }
+
+ inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
+ {
+ if (likely (has_glyph_classes))
+ buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
+ else if (class_guess)
+ buffer->cur().glyph_props() = class_guess;
+ }
+
+ inline void output_glyph (hb_codepoint_t glyph_index,
+ unsigned int class_guess = 0) const
+ {
+ set_class (glyph_index, class_guess);
+ buffer->output_glyph (glyph_index);
+ }
+ inline void replace_glyph (hb_codepoint_t glyph_index,
+ unsigned int class_guess = 0) const
+ {
+ set_class (glyph_index, class_guess);
+ buffer->replace_glyph (glyph_index);
+ }
+ inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
+ unsigned int class_guess = 0) const
+ {
+ set_class (glyph_index, class_guess);
+ buffer->cur().codepoint = glyph_index;
+ }
+};
+
+
+
+typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
+typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
+typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+
+struct ContextClosureFuncs
+{
+ intersects_func_t intersects;
+};
+struct ContextCollectGlyphsFuncs
+{
+ collect_glyphs_func_t collect;
+};
+struct ContextApplyFuncs
+{
+ match_func_t match;
+};
+
+
+static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+{
+ return glyphs->has (value);
+}
+static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data)
+{
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return class_def.intersects_class (glyphs, value);
+}
+static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ return (data+coverage).intersects (glyphs);
+}
+
+static inline bool intersects_array (hb_closure_context_t *c,
+ unsigned int count,
+ const USHORT values[],
+ intersects_func_t intersects_func,
+ const void *intersects_data)
+{
+ for (unsigned int i = 0; i < count; i++)
+ if (likely (!intersects_func (c->glyphs, values[i], intersects_data)))
+ return false;
+ return true;
+}
+
+
+static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+{
+ glyphs->add (value);
+}
+static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data)
+{
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ class_def.add_class (glyphs, value);
+}
+static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ (data+coverage).add_coverage (glyphs);
+}
+static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
+ hb_set_t *glyphs,
+ unsigned int count,
+ const USHORT values[],
+ collect_glyphs_func_t collect_func,
+ const void *collect_data)
+{
+ for (unsigned int i = 0; i < count; i++)
+ collect_func (glyphs, values[i], collect_data);
+}
+
+
+static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED)
+{
+ return glyph_id == value;
+}
+static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
+{
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return class_def.get_class (glyph_id) == value;
+}
+static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
+}
+
+static inline bool would_match_input (hb_would_apply_context_t *c,
+ unsigned int count, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ match_func_t match_func,
+ const void *match_data)
+{
+ if (count != c->len)
+ return false;
+
+ for (unsigned int i = 1; i < count; i++)
+ if (likely (!match_func (c->glyphs[i], input[i - 1], match_data)))
+ return false;
+
+ return true;
+}
+static inline bool match_input (hb_apply_context_t *c,
+ unsigned int count, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ match_func_t match_func,
+ const void *match_data,
+ unsigned int *end_offset = NULL,
+ bool *p_is_mark_ligature = NULL,
+ unsigned int *p_total_component_count = NULL)
+{
+ TRACE_APPLY (NULL);
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ skippy_iter.set_match_func (match_func, match_data, input);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
+
+ /*
+ * This is perhaps the trickiest part of OpenType... Remarks:
+ *
+ * - If all components of the ligature were marks, we call this a mark ligature.
+ *
+ * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize
+ * it as a ligature glyph.
+ *
+ * - Ligatures cannot be formed across glyphs attached to different components
+ * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
+ * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
+ * However, it would be wrong to ligate that SHADDA,FATHA sequence.o
+ * There is an exception to this: If a ligature tries ligating with marks that
+ * belong to it itself, go ahead, assuming that the font designer knows what
+ * they are doing (otherwise it can break Indic stuff when a matra wants to
+ * ligate with a conjunct...)
+ */
+
+ bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+
+ unsigned int total_component_count = 0;
+ total_component_count += get_lig_num_comps (c->buffer->cur());
+
+ unsigned int first_lig_id = get_lig_id (c->buffer->cur());
+ unsigned int first_lig_comp = get_lig_comp (c->buffer->cur());
+
+ for (unsigned int i = 1; i < count; i++)
+ {
+ if (!skippy_iter.next ()) return TRACE_RETURN (false);
+
+ unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
+ unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]);
+
+ if (first_lig_id && first_lig_comp) {
+ /* If first component was attached to a previous ligature component,
+ * all subsequent components should be attached to the same ligature
+ * component, otherwise we shouldn't ligate them. */
+ if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
+ return TRACE_RETURN (false);
+ } else {
+ /* If first component was NOT attached to a previous ligature component,
+ * all subsequent components should also NOT be attached to any ligature
+ * component, unless they are attached to the first component itself! */
+ if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
+ return TRACE_RETURN (false);
+ }
+
+ is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
+ }
+
+ if (end_offset)
+ *end_offset = skippy_iter.idx - c->buffer->idx + 1;
+
+ if (p_is_mark_ligature)
+ *p_is_mark_ligature = is_mark_ligature;
+
+ if (p_total_component_count)
+ *p_total_component_count = total_component_count;
+
+ return TRACE_RETURN (true);
+}
+static inline void ligate_input (hb_apply_context_t *c,
+ unsigned int count, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ match_func_t match_func,
+ const void *match_data,
+ hb_codepoint_t lig_glyph,
+ bool is_mark_ligature,
+ unsigned int total_component_count)
+{
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ skippy_iter.set_match_func (match_func, match_data, input);
+ if (skippy_iter.has_no_chance ()) return;
+
+ /*
+ * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
+ * the ligature to keep its old ligature id. This will allow it to attach to
+ * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH,
+ * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a
+ * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature
+ * later, we don't want them to lose their ligature id/component, otherwise
+ * GPOS will fail to correctly position the mark ligature on top of the
+ * LAM,LAM,HEH ligature. See:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=676343
+ *
+ * - If a ligature is formed of components that some of which are also ligatures
+ * themselves, and those ligature components had marks attached to *their*
+ * components, we have to attach the marks to the new ligature component
+ * positions! Now *that*'s tricky! And these marks may be following the
+ * last component of the whole sequence, so we should loop forward looking
+ * for them and update them.
+ *
+ * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a
+ * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature
+ * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature
+ * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to
+ * the new ligature with a component value of 2.
+ *
+ * This in fact happened to a font... See:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=437633
+ */
+
+ unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+ unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer);
+ unsigned int last_lig_id = get_lig_id (c->buffer->cur());
+ unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
+ unsigned int components_so_far = last_num_components;
+
+ if (!is_mark_ligature)
+ {
+ set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count);
+ if (_hb_glyph_info_get_general_category (&c->buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ _hb_glyph_info_set_general_category (&c->buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ }
+ c->replace_glyph (lig_glyph, klass);
+
+ for (unsigned int i = 1; i < count; i++)
+ {
+ if (!skippy_iter.next ()) return;
+
+ while (c->buffer->idx < skippy_iter.idx)
+ {
+ if (!is_mark_ligature) {
+ unsigned int new_lig_comp = components_so_far - last_num_components +
+ MIN (MAX (get_lig_comp (c->buffer->cur()), 1u), last_num_components);
+ set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp);
+ }
+ c->buffer->next_glyph ();
+ }
+
+ last_lig_id = get_lig_id (c->buffer->cur());
+ last_num_components = get_lig_num_comps (c->buffer->cur());
+ components_so_far += last_num_components;
+
+ /* Skip the base glyph */
+ c->buffer->idx++;
+ }
+
+ if (!is_mark_ligature && last_lig_id) {
+ /* Re-adjust components for any marks following. */
+ for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) {
+ if (last_lig_id == get_lig_id (c->buffer->info[i])) {
+ unsigned int new_lig_comp = components_so_far - last_num_components +
+ MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components);
+ set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp);
+ } else
+ break;
+ }
+ }
+}
+
+static inline bool match_backtrack (hb_apply_context_t *c,
+ unsigned int count,
+ const USHORT backtrack[],
+ match_func_t match_func,
+ const void *match_data)
+{
+ TRACE_APPLY (NULL);
+
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true);
+ skippy_iter.set_match_func (match_func, match_data, backtrack);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
+
+ for (unsigned int i = 0; i < count; i++)
+ if (!skippy_iter.prev ())
+ return TRACE_RETURN (false);
+
+ return TRACE_RETURN (true);
+}
+
+static inline bool match_lookahead (hb_apply_context_t *c,
+ unsigned int count,
+ const USHORT lookahead[],
+ match_func_t match_func,
+ const void *match_data,
+ unsigned int offset)
+{
+ TRACE_APPLY (NULL);
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true);
+ skippy_iter.set_match_func (match_func, match_data, lookahead);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
+
+ for (unsigned int i = 0; i < count; i++)
+ if (!skippy_iter.next ())
+ return TRACE_RETURN (false);
+
+ return TRACE_RETURN (true);
+}
+
+
+
+struct LookupRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ USHORT sequenceIndex; /* Index into current glyph
+ * sequence--first glyph = 0 */
+ USHORT lookupListIndex; /* Lookup to apply to that
+ * position--zero--based */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+
+template <typename context_t>
+static inline void recurse_lookups (context_t *c,
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
+{
+ for (unsigned int i = 0; i < lookupCount; i++)
+ c->recurse (lookupRecord[i].lookupListIndex);
+}
+
+static inline bool apply_lookup (hb_apply_context_t *c,
+ unsigned int count, /* Including the first glyph */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ match_func_t match_func,
+ const void *match_data,
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
+{
+ TRACE_APPLY (NULL);
+
+ unsigned int end = c->buffer->len;
+ if (unlikely (count == 0 || c->buffer->idx + count > end))
+ return TRACE_RETURN (false);
+
+ /* TODO We don't support lookupRecord arrays that are not increasing:
+ * Should be easy for in_place ones at least. */
+
+ /* Note: If sublookup is reverse, it will underflow after the first loop
+ * and we jump out of it. Not entirely disastrous. So we don't check
+ * for reverse lookup here.
+ */
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ skippy_iter.set_match_func (match_func, match_data, input);
+ uint8_t syllable = c->buffer->cur().syllable();
+
+ unsigned int i = 0;
+ if (lookupCount && 0 == lookupRecord->sequenceIndex)
+ {
+ unsigned int old_pos = c->buffer->idx;
+
+ /* Apply a lookup */
+ bool done = c->recurse (lookupRecord->lookupListIndex);
+
+ lookupRecord++;
+ lookupCount--;
+ i++;
+
+ if (!done)
+ goto not_applied;
+ else
+ {
+ if (c->table_index == 1)
+ c->buffer->idx = old_pos + 1;
+ /* Reinitialize iterator. */
+ hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
+ tmp.set_syllable (syllable);
+ skippy_iter = tmp;
+ }
+ }
+ else
+ {
+ not_applied:
+ /* No lookup applied for this index */
+ c->buffer->next_glyph ();
+ i++;
+ }
+ while (i < count)
+ {
+ if (!skippy_iter.next ()) return TRACE_RETURN (true);
+ while (c->buffer->idx < skippy_iter.idx)
+ c->buffer->next_glyph ();
+
+ if (lookupCount && i == lookupRecord->sequenceIndex)
+ {
+ unsigned int old_pos = c->buffer->idx;
+
+ /* Apply a lookup */
+ bool done = c->recurse (lookupRecord->lookupListIndex);
+
+ lookupRecord++;
+ lookupCount--;
+ i++;
+
+ if (!done)
+ goto not_applied2;
+ else
+ {
+ if (c->table_index == 1)
+ c->buffer->idx = old_pos + 1;
+ /* Reinitialize iterator. */
+ hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
+ tmp.set_syllable (syllable);
+ skippy_iter = tmp;
+ }
+ }
+ else
+ {
+ not_applied2:
+ /* No lookup applied for this index */
+ c->buffer->next_glyph ();
+ i++;
+ }
+ }
+
+ return TRACE_RETURN (true);
+}
+
+
+
+/* Contextual lookups */
+
+struct ContextClosureLookupContext
+{
+ ContextClosureFuncs funcs;
+ const void *intersects_data;
+};
+
+struct ContextCollectGlyphsLookupContext
+{
+ ContextCollectGlyphsFuncs funcs;
+ const void *collect_data;
+};
+
+struct ContextApplyLookupContext
+{
+ ContextApplyFuncs funcs;
+ const void *match_data;
+};
+
+static inline void context_closure_lookup (hb_closure_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextClosureLookupContext &lookup_context)
+{
+ if (intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data))
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextCollectGlyphsLookupContext &lookup_context)
+{
+ collect_array (c, c->input,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.collect, lookup_context.collect_data);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount HB_UNUSED,
+ const LookupRecord lookupRecord[] HB_UNUSED,
+ ContextApplyLookupContext &lookup_context)
+{
+ return would_match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data);
+}
+static inline bool context_apply_lookup (hb_apply_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextApplyLookupContext &lookup_context)
+{
+ return match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data)
+ && apply_lookup (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data,
+ lookupCount, lookupRecord);
+}
+
+struct Rule
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
+ unsigned int count = lookupCount;
+ for (unsigned int i = 0; i < count; i++)
+ if (!c->recurse (lookupRecord[i].lookupListIndex))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
+ context_closure_lookup (c,
+ inputCount, input,
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
+ context_collect_glyphs_lookup (c,
+ inputCount, input,
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
+ return TRACE_RETURN (context_would_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context));
+ }
+
+ inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
+ return TRACE_RETURN (context_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context));
+ }
+
+ public:
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return inputCount.sanitize (c)
+ && lookupCount.sanitize (c)
+ && c->check_range (input,
+ input[0].static_size * inputCount
+ + lookupRecordX[0].static_size * lookupCount);
+ }
+
+ protected:
+ USHORT inputCount; /* Total number of glyphs in input
+ * glyph sequence--includes the first
+ * glyph */
+ USHORT lookupCount; /* Number of LookupRecords */
+ USHORT input[VAR]; /* Array of match inputs--start with
+ * second glyph */
+ LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in
+ * design order */
+ public:
+ DEFINE_SIZE_ARRAY2 (4, input, lookupRecordX);
+};
+
+struct RuleSet
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ if (!(this+rule[i]).is_inplace (c))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).closure (c, lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ {
+ if ((this+rule[i]).would_apply (c, lookup_context))
+ return TRACE_RETURN (true);
+ }
+ return TRACE_RETURN (false);
+ }
+
+ inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ {
+ if ((this+rule[i]).apply (c, lookup_context))
+ return TRACE_RETURN (true);
+ }
+ return TRACE_RETURN (false);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (rule.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<Rule>
+ rule; /* Array of Rule tables
+ * ordered by preference */
+ public:
+ DEFINE_SIZE_ARRAY (2, rule);
+};
+
+
+struct ContextFormat1
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+ruleSet[i]).is_inplace (c))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+
+ const Coverage &cov = (this+coverage);
+
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_glyph},
+ NULL
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (cov.intersects_coverage (c->glyphs, i)) {
+ const RuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_glyph},
+ NULL
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ NULL
+ };
+ return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED))
+ return TRACE_RETURN (false);
+
+ const RuleSet &rule_set = this+ruleSet[index];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ NULL
+ };
+ return TRACE_RETURN (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetArrayOf<RuleSet>
+ ruleSet; /* Array of RuleSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, ruleSet);
+};
+
+
+struct ContextFormat2
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+ruleSet[i]).is_inplace (c))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ if (!(this+coverage).intersects (c->glyphs))
+ return;
+
+ const ClassDef &class_def = this+classDef;
+
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_class},
+ &class_def
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (class_def.intersects_class (c->glyphs, i)) {
+ const RuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ const ClassDef &class_def = this+classDef;
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_class},
+ &class_def
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const ClassDef &class_def = this+classDef;
+ unsigned int index = class_def.get_class (c->glyphs[0]);
+ const RuleSet &rule_set = this+ruleSet[index];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_class},
+ &class_def
+ };
+ return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const ClassDef &class_def = this+classDef;
+ index = class_def.get_class (c->buffer->cur().codepoint);
+ const RuleSet &rule_set = this+ruleSet[index];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_class},
+ &class_def
+ };
+ return TRACE_RETURN (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetTo<ClassDef>
+ classDef; /* Offset to glyph ClassDef table--from
+ * beginning of table */
+ OffsetArrayOf<RuleSet>
+ ruleSet; /* Array of RuleSet tables
+ * ordered by class */
+ public:
+ DEFINE_SIZE_ARRAY (8, ruleSet);
+};
+
+
+struct ContextFormat3
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
+ unsigned int count = lookupCount;
+ for (unsigned int i = 0; i < count; i++)
+ if (!c->recurse (lookupRecord[i].lookupListIndex))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ if (!(this+coverage[0]).intersects (c->glyphs))
+ return;
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_coverage},
+ this
+ };
+ context_closure_lookup (c,
+ glyphCount, (const USHORT *) (coverage + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage[0]).add_coverage (c->input);
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_coverage},
+ this
+ };
+
+ context_collect_glyphs_lookup (c,
+ glyphCount, (const USHORT *) (coverage + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
+ struct ContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ this
+ };
+ return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage[0];
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage[0]).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
+ struct ContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ this
+ };
+ return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!c->check_struct (this)) return TRACE_RETURN (false);
+ unsigned int count = glyphCount;
+ if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE_RETURN (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (!coverage[i].sanitize (c, this)) return TRACE_RETURN (false);
+ LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * count);
+ return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 3 */
+ USHORT glyphCount; /* Number of glyphs in the input glyph
+ * sequence */
+ USHORT lookupCount; /* Number of LookupRecords */
+ OffsetTo<Coverage>
+ coverage[VAR]; /* Array of offsets to Coverage
+ * table in glyph sequence order */
+ LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in
+ * design order */
+ public:
+ DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX);
+};
+
+struct Context
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ case 2: return TRACE_RETURN (c->dispatch (u.format2));
+ case 3: return TRACE_RETURN (c->dispatch (u.format3));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ case 3: return TRACE_RETURN (u.format3.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ ContextFormat1 format1;
+ ContextFormat2 format2;
+ ContextFormat3 format3;
+ } u;
+};
+
+
+/* Chaining Contextual lookups */
+
+struct ChainContextClosureLookupContext
+{
+ ContextClosureFuncs funcs;
+ const void *intersects_data[3];
+};
+
+struct ChainContextCollectGlyphsLookupContext
+{
+ ContextCollectGlyphsFuncs funcs;
+ const void *collect_data[3];
+};
+
+struct ChainContextApplyLookupContext
+{
+ ContextApplyFuncs funcs;
+ const void *match_data[3];
+};
+
+static inline void chain_context_closure_lookup (hb_closure_context_t *c,
+ unsigned int backtrackCount,
+ const USHORT backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const USHORT lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextClosureLookupContext &lookup_context)
+{
+ if (intersects_array (c,
+ backtrackCount, backtrack,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+ && intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+ && intersects_array (c,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[2]))
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
+ unsigned int backtrackCount,
+ const USHORT backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const USHORT lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextCollectGlyphsLookupContext &lookup_context)
+{
+ collect_array (c, c->before,
+ backtrackCount, backtrack,
+ lookup_context.funcs.collect, lookup_context.collect_data[0]);
+ collect_array (c, c->input,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.collect, lookup_context.collect_data[1]);
+ collect_array (c, c->after,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.collect, lookup_context.collect_data[2]);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
+ unsigned int backtrackCount,
+ const USHORT backtrack[] HB_UNUSED,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const USHORT lookahead[] HB_UNUSED,
+ unsigned int lookupCount HB_UNUSED,
+ const LookupRecord lookupRecord[] HB_UNUSED,
+ ChainContextApplyLookupContext &lookup_context)
+{
+ return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
+ && would_match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data[1]);
+}
+
+static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
+ unsigned int backtrackCount,
+ const USHORT backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const USHORT lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextApplyLookupContext &lookup_context)
+{
+ unsigned int lookahead_offset = 0;
+ return match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data[1],
+ &lookahead_offset)
+ && match_backtrack (c,
+ backtrackCount, backtrack,
+ lookup_context.funcs.match, lookup_context.match_data[0])
+ && match_lookahead (c,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.match, lookup_context.match_data[2],
+ lookahead_offset)
+ && apply_lookup (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data[1],
+ lookupCount, lookupRecord);
+}
+
+struct ChainRule
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ unsigned int count = lookup.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!c->recurse (lookup.array[i].lookupListIndex))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ chain_context_closure_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ chain_context_collect_glyphs_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ return TRACE_RETURN (chain_context_would_apply_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array, lookup.len,
+ lookup.array, lookup_context));
+ }
+
+ inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ return TRACE_RETURN (chain_context_apply_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array, lookup.len,
+ lookup.array, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!backtrack.sanitize (c)) return TRACE_RETURN (false);
+ HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ if (!input.sanitize (c)) return TRACE_RETURN (false);
+ ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ if (!lookahead.sanitize (c)) return TRACE_RETURN (false);
+ ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ return TRACE_RETURN (lookup.sanitize (c));
+ }
+
+ protected:
+ ArrayOf<USHORT>
+ backtrack; /* Array of backtracking values
+ * (to be matched before the input
+ * sequence) */
+ HeadlessArrayOf<USHORT>
+ inputX; /* Array of input values (start with
+ * second glyph) */
+ ArrayOf<USHORT>
+ lookaheadX; /* Array of lookahead values's (to be
+ * matched after the input sequence) */
+ ArrayOf<LookupRecord>
+ lookupX; /* Array of LookupRecords--in
+ * design order) */
+ public:
+ DEFINE_SIZE_MIN (8);
+};
+
+struct ChainRuleSet
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ if (!(this+rule[i]).is_inplace (c))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).closure (c, lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ if ((this+rule[i]).would_apply (c, lookup_context))
+ return TRACE_RETURN (true);
+
+ return TRACE_RETURN (false);
+ }
+
+ inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ if ((this+rule[i]).apply (c, lookup_context))
+ return TRACE_RETURN (true);
+
+ return TRACE_RETURN (false);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (rule.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<ChainRule>
+ rule; /* Array of ChainRule tables
+ * ordered by preference */
+ public:
+ DEFINE_SIZE_ARRAY (2, rule);
+};
+
+struct ChainContextFormat1
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+ruleSet[i]).is_inplace (c))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ const Coverage &cov = (this+coverage);
+
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_glyph},
+ {NULL, NULL, NULL}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (cov.intersects_coverage (c->glyphs, i)) {
+ const ChainRuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_glyph},
+ {NULL, NULL, NULL}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ {NULL, NULL, NULL}
+ };
+ return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const ChainRuleSet &rule_set = this+ruleSet[index];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ {NULL, NULL, NULL}
+ };
+ return TRACE_RETURN (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetArrayOf<ChainRuleSet>
+ ruleSet; /* Array of ChainRuleSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, ruleSet);
+};
+
+struct ChainContextFormat2
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+ruleSet[i]).is_inplace (c))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ if (!(this+coverage).intersects (c->glyphs))
+ return;
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (input_class_def.intersects_class (c->glyphs, i)) {
+ const ChainRuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ unsigned int index = input_class_def.get_class (c->glyphs[0]);
+ const ChainRuleSet &rule_set = this+ruleSet[index];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+ return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ index = input_class_def.get_class (c->buffer->cur().codepoint);
+ const ChainRuleSet &rule_set = this+ruleSet[index];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+ return TRACE_RETURN (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
+ inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
+ ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetTo<ClassDef>
+ backtrackClassDef; /* Offset to glyph ClassDef table
+ * containing backtrack sequence
+ * data--from beginning of table */
+ OffsetTo<ClassDef>
+ inputClassDef; /* Offset to glyph ClassDef
+ * table containing input sequence
+ * data--from beginning of table */
+ OffsetTo<ClassDef>
+ lookaheadClassDef; /* Offset to glyph ClassDef table
+ * containing lookahead sequence
+ * data--from beginning of table */
+ OffsetArrayOf<ChainRuleSet>
+ ruleSet; /* Array of ChainRuleSet tables
+ * ordered by class */
+ public:
+ DEFINE_SIZE_ARRAY (12, ruleSet);
+};
+
+struct ChainContextFormat3
+{
+ inline bool is_inplace (hb_is_inplace_context_t *c) const
+ {
+ TRACE_IS_INPLACE (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+
+ unsigned int count = lookup.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!c->recurse (lookup.array[i].lookupListIndex))
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ if (!(this+input[0]).intersects (c->glyphs))
+ return;
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_coverage},
+ {this, this, this}
+ };
+ chain_context_closure_lookup (c,
+ backtrack.len, (const USHORT *) backtrack.array,
+ input.len, (const USHORT *) input.array + 1,
+ lookahead.len, (const USHORT *) lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ (this+input[0]).add_coverage (c->input);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_coverage},
+ {this, this, this}
+ };
+ chain_context_collect_glyphs_lookup (c,
+ backtrack.len, (const USHORT *) backtrack.array,
+ input.len, (const USHORT *) input.array + 1,
+ lookahead.len, (const USHORT *) lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ {this, this, this}
+ };
+ return TRACE_RETURN (chain_context_would_apply_lookup (c,
+ backtrack.len, (const USHORT *) backtrack.array,
+ input.len, (const USHORT *) input.array + 1,
+ lookahead.len, (const USHORT *) lookahead.array,
+ lookup.len, lookup.array, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ return this+input[0];
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ {this, this, this}
+ };
+ return TRACE_RETURN (chain_context_apply_lookup (c,
+ backtrack.len, (const USHORT *) backtrack.array,
+ input.len, (const USHORT *) input.array + 1,
+ lookahead.len, (const USHORT *) lookahead.array,
+ lookup.len, lookup.array, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false);
+ OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ if (!input.sanitize (c, this)) return TRACE_RETURN (false);
+ OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false);
+ ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ return TRACE_RETURN (lookup.sanitize (c));
+ }
+
+ protected:
+ USHORT format; /* Format identifier--format = 3 */
+ OffsetArrayOf<Coverage>
+ backtrack; /* Array of coverage tables
+ * in backtracking sequence, in glyph
+ * sequence order */
+ OffsetArrayOf<Coverage>
+ inputX ; /* Array of coverage
+ * tables in input sequence, in glyph
+ * sequence order */
+ OffsetArrayOf<Coverage>
+ lookaheadX; /* Array of coverage tables
+ * in lookahead sequence, in glyph
+ * sequence order */
+ ArrayOf<LookupRecord>
+ lookupX; /* Array of LookupRecords--in
+ * design order) */
+ public:
+ DEFINE_SIZE_MIN (10);
+};
+
+struct ChainContext
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (c->dispatch (u.format1));
+ case 2: return TRACE_RETURN (c->dispatch (u.format2));
+ case 3: return TRACE_RETURN (c->dispatch (u.format3));
+ default:return TRACE_RETURN (c->default_return_value ());
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ case 2: return TRACE_RETURN (u.format2.sanitize (c));
+ case 3: return TRACE_RETURN (u.format3.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ ChainContextFormat1 format1;
+ ChainContextFormat2 format2;
+ ChainContextFormat3 format3;
+ } u;
+};
+
+
+struct ExtensionFormat1
+{
+ inline unsigned int get_type (void) const { return extensionLookupType; }
+ inline unsigned int get_offset (void) const { return extensionOffset; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ protected:
+ USHORT format; /* Format identifier. Set to 1. */
+ USHORT extensionLookupType; /* Lookup type of subtable referenced
+ * by ExtensionOffset (i.e. the
+ * extension subtable). */
+ ULONG extensionOffset; /* Offset to the extension subtable,
+ * of lookup type subtable. */
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+template <typename T>
+struct Extension
+{
+ inline unsigned int get_type (void) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_type ();
+ default:return 0;
+ }
+ }
+ inline unsigned int get_offset (void) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_offset ();
+ default:return 0;
+ }
+ }
+
+ template <typename X>
+ inline const X& get_subtable (void) const
+ {
+ unsigned int offset = get_offset ();
+ if (unlikely (!offset)) return Null(typename T::LookupSubTable);
+ return StructAtOffset<typename T::LookupSubTable> (this, offset);
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ());
+ }
+
+ inline bool sanitize_self (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false);
+ switch (u.format) {
+ case 1: return TRACE_RETURN (u.format1.sanitize (c));
+ default:return TRACE_RETURN (true);
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!sanitize_self (c)) return TRACE_RETURN (false);
+ unsigned int offset = get_offset ();
+ if (unlikely (!offset)) return TRACE_RETURN (true);
+ return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ()));
+ }
+
+ protected:
+ union {
+ USHORT format; /* Format identifier */
+ ExtensionFormat1 format1;
+ } u;
+};
+
+
+/*
+ * GSUB/GPOS Common
+ */
+
+struct GSUBGPOS
+{
+ static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB;
+ static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS;
+
+ inline unsigned int get_script_count (void) const
+ { return (this+scriptList).len; }
+ inline const Tag& get_script_tag (unsigned int i) const
+ { return (this+scriptList).get_tag (i); }
+ inline unsigned int get_script_tags (unsigned int start_offset,
+ unsigned int *script_count /* IN/OUT */,
+ hb_tag_t *script_tags /* OUT */) const
+ { return (this+scriptList).get_tags (start_offset, script_count, script_tags); }
+ inline const Script& get_script (unsigned int i) const
+ { return (this+scriptList)[i]; }
+ inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
+ { return (this+scriptList).find_index (tag, index); }
+
+ inline unsigned int get_feature_count (void) const
+ { return (this+featureList).len; }
+ inline const Tag& get_feature_tag (unsigned int i) const
+ { return (this+featureList).get_tag (i); }
+ inline unsigned int get_feature_tags (unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ hb_tag_t *feature_tags /* OUT */) const
+ { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); }
+ inline const Feature& get_feature (unsigned int i) const
+ { return (this+featureList)[i]; }
+ inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const
+ { return (this+featureList).find_index (tag, index); }
+
+ inline unsigned int get_lookup_count (void) const
+ { return (this+lookupList).len; }
+ inline const Lookup& get_lookup (unsigned int i) const
+ { return (this+lookupList)[i]; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
+ scriptList.sanitize (c, this) &&
+ featureList.sanitize (c, this) &&
+ lookupList.sanitize (c, this));
+ }
+
+ protected:
+ FixedVersion version; /* Version of the GSUB/GPOS table--initially set
+ * to 0x00010000 */
+ OffsetTo<ScriptList>
+ scriptList; /* ScriptList table */
+ OffsetTo<FeatureList>
+ featureList; /* FeatureList table */
+ OffsetTo<LookupList>
+ lookupList; /* LookupList table */
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
new file mode 100644
index 0000000000..c5ba8b4b4d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
@@ -0,0 +1,296 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_PRIVATE_HH
+#define HB_OT_LAYOUT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-layout.h"
+
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+#include "hb-set-private.hh"
+
+
+/* buffer var allocations, used during the GSUB/GPOS processing */
+#define glyph_props() var1.u16[0] /* GDEF glyph properties */
+#define syllable() var1.u8[2] /* GSUB/GPOS shaping boundaries */
+#define lig_props() var1.u8[3] /* GSUB/GPOS ligature tracking */
+
+/* buffer var allocations, used during the entire shaping process */
+#define unicode_props0() var2.u8[0]
+#define unicode_props1() var2.u8[1]
+
+
+inline void
+_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
+{
+ info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
+ (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
+ (info->codepoint == 0x200C ? 0x40 : 0) |
+ (info->codepoint == 0x200D ? 0x20 : 0);
+ info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
+}
+
+inline void
+_hb_glyph_info_set_general_category (hb_glyph_info_t *info, hb_unicode_general_category_t gen_cat)
+{
+ info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~0x1F);
+}
+
+inline hb_unicode_general_category_t
+_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
+{
+ return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F);
+}
+
+inline void
+_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
+{
+ info->unicode_props1() = modified_class;
+}
+
+inline unsigned int
+_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
+{
+ return info->unicode_props1();
+}
+
+inline hb_bool_t
+_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
+{
+ return !!(info->unicode_props0() & 0x80);
+}
+
+inline hb_bool_t
+_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
+{
+ return !!(info->unicode_props0() & 0x40);
+}
+
+inline hb_bool_t
+_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
+{
+ return !!(info->unicode_props0() & 0x20);
+}
+
+
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
+
+/*
+ * GDEF
+ */
+
+typedef enum {
+ HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED = 1 << HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED,
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 1 << HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH,
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 1 << HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE,
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK = 1 << HB_OT_LAYOUT_GLYPH_CLASS_MARK,
+ HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT = 1 << HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT
+} hb_ot_layout_glyph_class_mask_t;
+
+
+
+/*
+ * GSUB/GPOS
+ */
+
+/* lig_id / lig_comp
+ *
+ * When a ligature is formed:
+ *
+ * - The ligature glyph and any marks in between all the same newly allocated
+ * lig_id,
+ * - The ligature glyph will get lig_num_comps set to the number of components
+ * - The marks get lig_comp > 0, reflecting which component of the ligature
+ * they were applied to.
+ * - This is used in GPOS to attach marks to the right component of a ligature
+ * in MarkLigPos.
+ *
+ * When a multiple-substitution is done:
+ *
+ * - All resulting glyphs will have lig_id = 0,
+ * - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
+ * - This is used in GPOS to attach marks to the first component of a
+ * multiple substitution in MarkBasePos.
+ *
+ * The numbers are also used in GPOS to do mark-to-mark positioning only
+ * to marks that belong to the same component of a ligature in MarkMarPos.
+ */
+#define IS_LIG_BASE 0x10
+static inline void
+set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps)
+{
+ info.lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
+}
+static inline void
+set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp)
+{
+ info.lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
+}
+static inline void
+set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp)
+{
+ set_lig_props_for_mark (info, 0, comp);
+}
+
+static inline unsigned int
+get_lig_id (const hb_glyph_info_t &info)
+{
+ return info.lig_props() >> 5;
+}
+static inline bool
+is_a_ligature (const hb_glyph_info_t &info)
+{
+ return !!(info.lig_props() & IS_LIG_BASE);
+}
+static inline unsigned int
+get_lig_comp (const hb_glyph_info_t &info)
+{
+ if (is_a_ligature (info))
+ return 0;
+ else
+ return info.lig_props() & 0x0F;
+}
+static inline unsigned int
+get_lig_num_comps (const hb_glyph_info_t &info)
+{
+ if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info))
+ return info.lig_props() & 0x0F;
+ else
+ return 1;
+}
+
+static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
+ uint8_t lig_id = buffer->next_serial () & 0x07;
+ if (unlikely (!lig_id))
+ lig_id = allocate_lig_id (buffer); /* in case of overflow */
+ return lig_id;
+}
+
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context);
+
+
+/* Should be called before all the substitute_lookup's are done. */
+HB_INTERNAL void
+hb_ot_layout_substitute_start (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+struct hb_ot_layout_lookup_accelerator_t;
+
+namespace OT {
+ struct hb_apply_context_t;
+ struct SubstLookup;
+}
+
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+ const OT::SubstLookup &lookup,
+ const hb_ot_layout_lookup_accelerator_t &accel);
+
+
+/* Should be called after all the substitute_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_substitute_finish (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+/* Should be called before all the position_lookup's are done. Resets positions to zero. */
+HB_INTERNAL void
+hb_ot_layout_position_start (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+/* Should be called after all the position_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_position_finish (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+
+/*
+ * hb_ot_layout_t
+ */
+
+namespace OT {
+ struct GDEF;
+ struct GSUB;
+ struct GPOS;
+}
+
+struct hb_ot_layout_lookup_accelerator_t
+{
+ template <typename TLookup>
+ inline void init (const TLookup &lookup)
+ {
+ digest.init ();
+ lookup.add_coverage (&digest);
+ }
+
+ template <typename TLookup>
+ inline void fini (const TLookup &lookup)
+ {
+ }
+
+ hb_set_digest_t digest;
+};
+
+struct hb_ot_layout_t
+{
+ hb_blob_t *gdef_blob;
+ hb_blob_t *gsub_blob;
+ hb_blob_t *gpos_blob;
+
+ const struct OT::GDEF *gdef;
+ const struct OT::GSUB *gsub;
+ const struct OT::GPOS *gpos;
+
+ unsigned int gsub_lookup_count;
+ unsigned int gpos_lookup_count;
+
+ hb_ot_layout_lookup_accelerator_t *gsub_accels;
+ hb_ot_layout_lookup_accelerator_t *gpos_accels;
+};
+
+
+HB_INTERNAL hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face);
+
+HB_INTERNAL void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+
+
+
+#endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
new file mode 100644
index 0000000000..520deff710
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
@@ -0,0 +1,910 @@
+/*
+ * Copyright © 1998-2004 David Turner and Werner Lemberg
+ * Copyright © 2006 Behdad Esfahbod
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-layout-private.hh"
+
+#include "hb-ot-layout-gdef-table.hh"
+#include "hb-ot-layout-gsub-table.hh"
+#include "hb-ot-layout-gpos-table.hh"
+
+#include "hb-ot-map-private.hh"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
+
+hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face)
+{
+ hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+ if (unlikely (!layout))
+ return NULL;
+
+ layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF));
+ layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
+
+ layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB));
+ layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
+
+ layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS));
+ layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
+
+ layout->gsub_lookup_count = layout->gsub->get_lookup_count ();
+ layout->gpos_lookup_count = layout->gpos->get_lookup_count ();
+
+ layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
+ layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
+
+ if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) ||
+ (layout->gpos_lookup_count && !layout->gpos_accels)))
+ {
+ _hb_ot_layout_destroy (layout);
+ return NULL;
+ }
+
+ for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
+ layout->gsub_accels[i].init (layout->gsub->get_lookup (i));
+ for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
+ layout->gpos_accels[i].init (layout->gpos->get_lookup (i));
+
+ return layout;
+}
+
+void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout)
+{
+ for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
+ layout->gsub_accels[i].fini (layout->gsub->get_lookup (i));
+ for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
+ layout->gpos_accels[i].fini (layout->gpos->get_lookup (i));
+
+ free (layout->gsub_accels);
+ free (layout->gpos_accels);
+
+ hb_blob_destroy (layout->gdef_blob);
+ hb_blob_destroy (layout->gsub_blob);
+ hb_blob_destroy (layout->gpos_blob);
+
+ free (layout);
+}
+
+static inline const OT::GDEF&
+_get_gdef (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF);
+ return *hb_ot_layout_from_face (face)->gdef;
+}
+static inline const OT::GSUB&
+_get_gsub (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB);
+ return *hb_ot_layout_from_face (face)->gsub;
+}
+static inline const OT::GPOS&
+_get_gpos (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS);
+ return *hb_ot_layout_from_face (face)->gpos;
+}
+
+
+/*
+ * GDEF
+ */
+
+hb_bool_t
+hb_ot_layout_has_glyph_classes (hb_face_t *face)
+{
+ return _get_gdef (face).has_glyph_classes ();
+}
+
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (hb_face_t *face,
+ hb_codepoint_t glyph)
+{
+ return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph);
+}
+
+void
+hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
+ hb_ot_layout_glyph_class_t klass,
+ hb_set_t *glyphs /* OUT */)
+{
+ return _get_gdef (face).get_glyphs_in_class (klass, glyphs);
+}
+
+unsigned int
+hb_ot_layout_get_attach_points (hb_face_t *face,
+ hb_codepoint_t glyph,
+ unsigned int start_offset,
+ unsigned int *point_count /* IN/OUT */,
+ unsigned int *point_array /* OUT */)
+{
+ return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
+}
+
+unsigned int
+hb_ot_layout_get_ligature_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ int *caret_array /* OUT */)
+{
+ return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
+}
+
+
+/*
+ * GSUB/GPOS
+ */
+
+static const OT::GSUBGPOS&
+get_gsubgpos_table (hb_face_t *face,
+ hb_tag_t table_tag)
+{
+ switch (table_tag) {
+ case HB_OT_TAG_GSUB: return _get_gsub (face);
+ case HB_OT_TAG_GPOS: return _get_gpos (face);
+ default: return OT::Null(OT::GSUBGPOS);
+ }
+}
+
+
+unsigned int
+hb_ot_layout_table_get_script_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int start_offset,
+ unsigned int *script_count /* IN/OUT */,
+ hb_tag_t *script_tags /* OUT */)
+{
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+ return g.get_script_tags (start_offset, script_count, script_tags);
+}
+
+#define HB_OT_TAG_LATIN_SCRIPT HB_TAG ('l', 'a', 't', 'n')
+
+hb_bool_t
+hb_ot_layout_table_find_script (hb_face_t *face,
+ hb_tag_t table_tag,
+ hb_tag_t script_tag,
+ unsigned int *script_index)
+{
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+ if (g.find_script_index (script_tag, script_index))
+ return true;
+
+ /* try finding 'DFLT' */
+ if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
+ return false;
+
+ /* try with 'dflt'; MS site has had typos and many fonts use it now :(.
+ * including many versions of DejaVu Sans Mono! */
+ if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
+ return false;
+
+ /* try with 'latn'; some old fonts put their features there even though
+ they're really trying to support Thai, for example :( */
+ if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index))
+ return false;
+
+ if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+ return false;
+}
+
+hb_bool_t
+hb_ot_layout_table_choose_script (hb_face_t *face,
+ hb_tag_t table_tag,
+ const hb_tag_t *script_tags,
+ unsigned int *script_index,
+ hb_tag_t *chosen_script)
+{
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+ while (*script_tags)
+ {
+ if (g.find_script_index (*script_tags, script_index)) {
+ if (chosen_script)
+ *chosen_script = *script_tags;
+ return true;
+ }
+ script_tags++;
+ }
+
+ /* try finding 'DFLT' */
+ if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) {
+ if (chosen_script)
+ *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT;
+ return false;
+ }
+
+ /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
+ if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) {
+ if (chosen_script)
+ *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE;
+ return false;
+ }
+
+ /* try with 'latn'; some old fonts put their features there even though
+ they're really trying to support Thai, for example :( */
+ if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) {
+ if (chosen_script)
+ *chosen_script = HB_OT_TAG_LATIN_SCRIPT;
+ return false;
+ }
+
+ if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+ if (chosen_script)
+ *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+ return false;
+}
+
+unsigned int
+hb_ot_layout_table_get_feature_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ hb_tag_t *feature_tags /* OUT */)
+{
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+ return g.get_feature_tags (start_offset, feature_count, feature_tags);
+}
+
+
+unsigned int
+hb_ot_layout_script_get_language_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int start_offset,
+ unsigned int *language_count /* IN/OUT */,
+ hb_tag_t *language_tags /* OUT */)
+{
+ const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
+
+ return s.get_lang_sys_tags (start_offset, language_count, language_tags);
+}
+
+hb_bool_t
+hb_ot_layout_script_find_language (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ hb_tag_t language_tag,
+ unsigned int *language_index)
+{
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
+ const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
+
+ if (s.find_lang_sys_index (language_tag, language_index))
+ return true;
+
+ /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
+ if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
+ return false;
+
+ if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
+ return false;
+}
+
+hb_bool_t
+hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ unsigned int *feature_index)
+{
+ const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
+
+ if (feature_index) *feature_index = l.get_required_feature_index ();
+
+ return l.has_required_feature ();
+}
+
+unsigned int
+hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ unsigned int *feature_indexes /* OUT */)
+{
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+ return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
+}
+
+unsigned int
+hb_ot_layout_language_get_feature_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ hb_tag_t *feature_tags /* OUT */)
+{
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+ ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
+ unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
+
+ if (feature_tags) {
+ unsigned int count = *feature_count;
+ for (unsigned int i = 0; i < count; i++)
+ feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
+ }
+
+ return ret;
+}
+
+
+hb_bool_t
+hb_ot_layout_language_find_feature (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ hb_tag_t feature_tag,
+ unsigned int *feature_index)
+{
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+ unsigned int num_features = l.get_feature_count ();
+ for (unsigned int i = 0; i < num_features; i++) {
+ unsigned int f_index = l.get_feature_index (i);
+
+ if (feature_tag == g.get_feature_tag (f_index)) {
+ if (feature_index) *feature_index = f_index;
+ return true;
+ }
+ }
+
+ if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
+ return false;
+}
+
+unsigned int
+hb_ot_layout_feature_get_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int feature_index,
+ unsigned int start_offset,
+ unsigned int *lookup_count /* IN/OUT */,
+ unsigned int *lookup_indexes /* OUT */)
+{
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::Feature &f = g.get_feature (feature_index);
+
+ return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
+}
+
+static void
+_hb_ot_layout_collect_lookups_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int feature_index,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ unsigned int lookup_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (lookup_indices);
+ hb_ot_layout_feature_get_lookups (face,
+ table_tag,
+ feature_index,
+ offset, &len,
+ lookup_indices);
+
+ for (unsigned int i = 0; i < len; i++)
+ lookup_indexes->add (lookup_indices[i]);
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (lookup_indices));
+}
+
+static void
+_hb_ot_layout_collect_lookups_features (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ if (!features)
+ {
+ unsigned int required_feature_index;
+ if (hb_ot_layout_language_get_required_feature_index (face,
+ table_tag,
+ script_index,
+ language_index,
+ &required_feature_index))
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ required_feature_index,
+ lookup_indexes);
+
+ /* All features */
+ unsigned int feature_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (feature_indices);
+ hb_ot_layout_language_get_feature_indexes (face,
+ table_tag,
+ script_index,
+ language_index,
+ offset, &len,
+ feature_indices);
+
+ for (unsigned int i = 0; i < len; i++)
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ feature_indices[i],
+ lookup_indexes);
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (feature_indices));
+ }
+ else
+ {
+ for (; *features; features++)
+ {
+ unsigned int feature_index;
+ if (hb_ot_layout_language_find_feature (face,
+ table_tag,
+ script_index,
+ language_index,
+ *features,
+ &feature_index))
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ feature_index,
+ lookup_indexes);
+ }
+ }
+}
+
+static void
+_hb_ot_layout_collect_lookups_languages (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
+ features,
+ lookup_indexes);
+
+ if (!languages)
+ {
+ /* All languages */
+ unsigned int count = hb_ot_layout_script_get_language_tags (face,
+ table_tag,
+ script_index,
+ 0, NULL, NULL);
+ for (unsigned int language_index = 0; language_index < count; language_index++)
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ language_index,
+ features,
+ lookup_indexes);
+ }
+ else
+ {
+ for (; *languages; languages++)
+ {
+ unsigned int language_index;
+ if (hb_ot_layout_script_find_language (face,
+ table_tag,
+ script_index,
+ *languages,
+ &language_index))
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ language_index,
+ features,
+ lookup_indexes);
+ }
+ }
+}
+
+void
+hb_ot_layout_collect_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ const hb_tag_t *scripts,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ if (!scripts)
+ {
+ /* All scripts */
+ unsigned int count = hb_ot_layout_table_get_script_tags (face,
+ table_tag,
+ 0, NULL, NULL);
+ for (unsigned int script_index = 0; script_index < count; script_index++)
+ _hb_ot_layout_collect_lookups_languages (face,
+ table_tag,
+ script_index,
+ languages,
+ features,
+ lookup_indexes);
+ }
+ else
+ {
+ for (; *scripts; scripts++)
+ {
+ unsigned int script_index;
+ if (hb_ot_layout_table_find_script (face,
+ table_tag,
+ *scripts,
+ &script_index))
+ _hb_ot_layout_collect_lookups_languages (face,
+ table_tag,
+ script_index,
+ languages,
+ features,
+ lookup_indexes);
+ }
+ }
+}
+
+void
+hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ hb_set_t *glyphs_before, /* OUT. May be NULL */
+ hb_set_t *glyphs_input, /* OUT. May be NULL */
+ hb_set_t *glyphs_after, /* OUT. May be NULL */
+ hb_set_t *glyphs_output /* OUT. May be NULL */)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
+
+ OT::hb_collect_glyphs_context_t c (face,
+ glyphs_before,
+ glyphs_input,
+ glyphs_after,
+ glyphs_output);
+
+ switch (table_tag)
+ {
+ case HB_OT_TAG_GSUB:
+ {
+ const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
+ l.collect_glyphs (&c);
+ return;
+ }
+ case HB_OT_TAG_GPOS:
+ {
+ const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index);
+ l.collect_glyphs (&c);
+ return;
+ }
+ }
+}
+
+
+/*
+ * OT::GSUB
+ */
+
+hb_bool_t
+hb_ot_layout_has_substitution (hb_face_t *face)
+{
+ return &_get_gsub (face) != &OT::Null(OT::GSUB);
+}
+
+hb_bool_t
+hb_ot_layout_lookup_would_substitute (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
+ return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
+}
+
+hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context)
+{
+ if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false;
+ OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context);
+
+ const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
+
+ return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest);
+}
+
+void
+hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer)
+{
+ OT::GSUB::substitute_start (font, buffer);
+}
+
+void
+hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer)
+{
+ OT::GSUB::substitute_finish (font, buffer);
+}
+
+void
+hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
+ unsigned int lookup_index,
+ hb_set_t *glyphs)
+{
+ OT::hb_closure_context_t c (face, glyphs);
+
+ const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
+
+ l.closure (&c);
+}
+
+/*
+ * OT::GPOS
+ */
+
+hb_bool_t
+hb_ot_layout_has_positioning (hb_face_t *face)
+{
+ return &_get_gpos (face) != &OT::Null(OT::GPOS);
+}
+
+void
+hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
+{
+ OT::GPOS::position_start (font, buffer);
+}
+
+void
+hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer)
+{
+ OT::GPOS::position_finish (font, buffer);
+}
+
+hb_bool_t
+hb_ot_layout_get_size_params (hb_face_t *face,
+ unsigned int *design_size, /* OUT. May be NULL */
+ unsigned int *subfamily_id, /* OUT. May be NULL */
+ unsigned int *subfamily_name_id, /* OUT. May be NULL */
+ unsigned int *range_start, /* OUT. May be NULL */
+ unsigned int *range_end /* OUT. May be NULL */)
+{
+ const OT::GPOS &gpos = _get_gpos (face);
+ const hb_tag_t tag = HB_TAG ('s','i','z','e');
+
+ unsigned int num_features = gpos.get_feature_count ();
+ for (unsigned int i = 0; i < num_features; i++)
+ {
+ if (tag == gpos.get_feature_tag (i))
+ {
+ const OT::Feature &f = gpos.get_feature (i);
+ const OT::FeatureParamsSize &params = f.get_feature_params ().get_size_params (tag);
+
+ if (params.designSize)
+ {
+#define PARAM(a, A) if (a) *a = params.A
+ PARAM (design_size, designSize);
+ PARAM (subfamily_id, subfamilyID);
+ PARAM (subfamily_name_id, subfamilyNameID);
+ PARAM (range_start, rangeStart);
+ PARAM (range_end, rangeEnd);
+#undef PARAM
+
+ return true;
+ }
+ }
+ }
+
+#define PARAM(a, A) if (a) *a = 0
+ PARAM (design_size, designSize);
+ PARAM (subfamily_id, subfamilyID);
+ PARAM (subfamily_name_id, subfamilyNameID);
+ PARAM (range_start, rangeStart);
+ PARAM (range_end, rangeEnd);
+#undef PARAM
+
+ return false;
+}
+
+
+/*
+ * Parts of different types are implemented here such that they have direct
+ * access to GSUB/GPOS lookups.
+ */
+
+
+struct GSUBProxy
+{
+ static const unsigned int table_index = 0;
+ typedef OT::SubstLookup Lookup;
+
+ GSUBProxy (hb_face_t *face) :
+ table (*hb_ot_layout_from_face (face)->gsub),
+ accels (hb_ot_layout_from_face (face)->gsub_accels) {}
+
+ const OT::GSUB &table;
+ const hb_ot_layout_lookup_accelerator_t *accels;
+};
+
+struct GPOSProxy
+{
+ static const unsigned int table_index = 1;
+ typedef OT::PosLookup Lookup;
+
+ GPOSProxy (hb_face_t *face) :
+ table (*hb_ot_layout_from_face (face)->gpos),
+ accels (hb_ot_layout_from_face (face)->gpos_accels) {}
+
+ const OT::GPOS &table;
+ const hb_ot_layout_lookup_accelerator_t *accels;
+};
+
+
+template <typename Lookup>
+static inline bool apply_once (OT::hb_apply_context_t *c,
+ const Lookup &lookup)
+{
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
+ return false;
+ return lookup.dispatch (c);
+}
+
+template <typename Proxy>
+static inline bool
+apply_string (OT::hb_apply_context_t *c,
+ const typename Proxy::Lookup &lookup,
+ const hb_ot_layout_lookup_accelerator_t &accel)
+{
+ bool ret = false;
+ OT::hb_is_inplace_context_t inplace_c (c->face);
+ bool inplace = lookup.is_inplace (&inplace_c);
+
+ if (unlikely (!c->buffer->len || !c->lookup_mask))
+ return false;
+
+ c->set_lookup (lookup);
+
+ if (likely (!lookup.is_reverse ()))
+ {
+ /* in/out forward substitution/positioning */
+ if (Proxy::table_index == 0)
+ c->buffer->clear_output ();
+ c->buffer->idx = 0;
+
+ while (c->buffer->idx < c->buffer->len)
+ {
+ if (accel.digest.may_have (c->buffer->cur().codepoint) &&
+ (c->buffer->cur().mask & c->lookup_mask) &&
+ apply_once (c, lookup))
+ ret = true;
+ else
+ c->buffer->next_glyph ();
+ }
+ if (ret)
+ {
+ if (!inplace)
+ c->buffer->swap_buffers ();
+ else
+ assert (!c->buffer->has_separate_output ());
+ }
+ }
+ else
+ {
+ /* in-place backward substitution/positioning */
+ if (Proxy::table_index == 0)
+ c->buffer->remove_output ();
+ c->buffer->idx = c->buffer->len - 1;
+ do
+ {
+ if (accel.digest.may_have (c->buffer->cur().codepoint) &&
+ (c->buffer->cur().mask & c->lookup_mask) &&
+ apply_once (c, lookup))
+ ret = true;
+ else
+ c->buffer->idx--;
+
+ }
+ while ((int) c->buffer->idx >= 0);
+ }
+
+ return ret;
+}
+
+template <typename Proxy>
+inline void hb_ot_map_t::apply (const Proxy &proxy,
+ const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer) const
+{
+ const unsigned int table_index = proxy.table_index;
+ unsigned int i = 0;
+ OT::hb_apply_context_t c (table_index, font, buffer);
+ c.set_recurse_func (Proxy::Lookup::apply_recurse_func);
+
+ for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) {
+ const stage_map_t *stage = &stages[table_index][stage_index];
+ for (; i < stage->last_lookup; i++)
+ {
+ unsigned int lookup_index = lookups[table_index][i].index;
+ c.set_lookup_mask (lookups[table_index][i].mask);
+ c.set_auto_zwj (lookups[table_index][i].auto_zwj);
+ apply_string<Proxy> (&c,
+ proxy.table.get_lookup (lookup_index),
+ proxy.accels[lookup_index]);
+ }
+
+ if (stage->pause_func)
+ {
+ buffer->clear_output ();
+ stage->pause_func (plan, font, buffer);
+ }
+ }
+}
+
+void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
+{
+ GSUBProxy proxy (font->face);
+ apply (proxy, plan, font, buffer);
+}
+
+void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
+{
+ GPOSProxy proxy (font->face);
+ apply (proxy, plan, font, buffer);
+}
+
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+ const OT::SubstLookup &lookup,
+ const hb_ot_layout_lookup_accelerator_t &accel)
+{
+ apply_string<GSUBProxy> (c, lookup, accel);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
new file mode 100644
index 0000000000..134f1a6c16
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_LAYOUT_H
+#define HB_OT_LAYOUT_H
+
+#include "hb.h"
+
+#include "hb-ot-tag.h"
+
+HB_BEGIN_DECLS
+
+
+#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
+#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
+#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
+
+
+/*
+ * GDEF
+ */
+
+hb_bool_t
+hb_ot_layout_has_glyph_classes (hb_face_t *face);
+
+typedef enum {
+ HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0,
+ HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 1,
+ HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 2,
+ HB_OT_LAYOUT_GLYPH_CLASS_MARK = 3,
+ HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4
+} hb_ot_layout_glyph_class_t;
+
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (hb_face_t *face,
+ hb_codepoint_t glyph);
+
+void
+hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
+ hb_ot_layout_glyph_class_t klass,
+ hb_set_t *glyphs /* OUT */);
+
+
+/* Not that useful. Provides list of attach points for a glyph that a
+ * client may want to cache */
+unsigned int
+hb_ot_layout_get_attach_points (hb_face_t *face,
+ hb_codepoint_t glyph,
+ unsigned int start_offset,
+ unsigned int *point_count /* IN/OUT */,
+ unsigned int *point_array /* OUT */);
+
+/* Ligature caret positions */
+unsigned int
+hb_ot_layout_get_ligature_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ hb_position_t *caret_array /* OUT */);
+
+
+/*
+ * GSUB/GPOS feature query and enumeration interface
+ */
+
+#define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF)
+#define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF)
+#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF)
+
+unsigned int
+hb_ot_layout_table_get_script_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int start_offset,
+ unsigned int *script_count /* IN/OUT */,
+ hb_tag_t *script_tags /* OUT */);
+
+hb_bool_t
+hb_ot_layout_table_find_script (hb_face_t *face,
+ hb_tag_t table_tag,
+ hb_tag_t script_tag,
+ unsigned int *script_index);
+
+/* Like find_script, but takes zero-terminated array of scripts to test */
+hb_bool_t
+hb_ot_layout_table_choose_script (hb_face_t *face,
+ hb_tag_t table_tag,
+ const hb_tag_t *script_tags,
+ unsigned int *script_index,
+ hb_tag_t *chosen_script);
+
+unsigned int
+hb_ot_layout_table_get_feature_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ hb_tag_t *feature_tags /* OUT */);
+
+unsigned int
+hb_ot_layout_script_get_language_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int start_offset,
+ unsigned int *language_count /* IN/OUT */,
+ hb_tag_t *language_tags /* OUT */);
+
+hb_bool_t
+hb_ot_layout_script_find_language (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ hb_tag_t language_tag,
+ unsigned int *language_index);
+
+hb_bool_t
+hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ unsigned int *feature_index);
+
+unsigned int
+hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ unsigned int *feature_indexes /* OUT */);
+
+unsigned int
+hb_ot_layout_language_get_feature_tags (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ hb_tag_t *feature_tags /* OUT */);
+
+hb_bool_t
+hb_ot_layout_language_find_feature (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ hb_tag_t feature_tag,
+ unsigned int *feature_index);
+
+unsigned int
+hb_ot_layout_feature_get_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int feature_index,
+ unsigned int start_offset,
+ unsigned int *lookup_count /* IN/OUT */,
+ unsigned int *lookup_indexes /* OUT */);
+
+void
+hb_ot_layout_collect_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ const hb_tag_t *scripts,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */);
+
+void
+hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
+ hb_tag_t table_tag,
+ hb_set_t *lookup_indexes /* OUT */);
+
+void
+hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ hb_set_t *glyphs_before, /* OUT. May be NULL */
+ hb_set_t *glyphs_input, /* OUT. May be NULL */
+ hb_set_t *glyphs_after, /* OUT. May be NULL */
+ hb_set_t *glyphs_output /* OUT. May be NULL */);
+
+#ifdef HB_NOT_IMPLEMENTED
+typedef struct
+{
+ const hb_codepoint_t *before,
+ unsigned int before_length,
+ const hb_codepoint_t *input,
+ unsigned int input_length,
+ const hb_codepoint_t *after,
+ unsigned int after_length,
+} hb_ot_layout_glyph_sequence_t;
+
+typedef hb_bool_t
+(*hb_ot_layout_glyph_sequence_func_t) (hb_font_t *font,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ void *user_data);
+
+void
+Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ hb_ot_layout_glyph_sequence_func_t callback,
+ void *user_data);
+#endif
+
+
+/*
+ * GSUB
+ */
+
+hb_bool_t
+hb_ot_layout_has_substitution (hb_face_t *face);
+
+hb_bool_t
+hb_ot_layout_lookup_would_substitute (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context);
+
+void
+hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
+ unsigned int lookup_index,
+ hb_set_t *glyphs
+ /*TODO , hb_bool_t inclusive */);
+
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
+hb_bool_t
+Xhb_ot_layout_lookup_substitute (hb_font_t *font,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ unsigned int out_size,
+ hb_codepoint_t *glyphs_out, /* OUT */
+ unsigned int *clusters_out, /* OUT */
+ unsigned int *out_length /* OUT */);
+#endif
+
+
+/*
+ * GPOS
+ */
+
+hb_bool_t
+hb_ot_layout_has_positioning (hb_face_t *face);
+
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
+hb_bool_t
+Xhb_ot_layout_lookup_position (hb_font_t *font,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ hb_glyph_position_t *positions /* IN / OUT */);
+#endif
+
+/* Optical 'size' feature info. Returns true if found.
+ * http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+hb_bool_t
+hb_ot_layout_get_size_params (hb_face_t *face,
+ unsigned int *design_size, /* OUT. May be NULL */
+ unsigned int *subfamily_id, /* OUT. May be NULL */
+ unsigned int *subfamily_name_id, /* OUT. May be NULL */
+ unsigned int *range_start, /* OUT. May be NULL */
+ unsigned int *range_end /* OUT. May be NULL */);
+
+
+HB_END_DECLS
+
+#endif /* HB_OT_LAYOUT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
new file mode 100644
index 0000000000..0e718a6f1f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
@@ -0,0 +1,247 @@
+/*
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2010,2011,2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_MAP_PRIVATE_HH
+#define HB_OT_MAP_PRIVATE_HH
+
+#include "hb-buffer-private.hh"
+
+
+struct hb_ot_shape_plan_t;
+
+static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
+
+struct hb_ot_map_t
+{
+ friend struct hb_ot_map_builder_t;
+
+ public:
+
+ struct feature_map_t {
+ hb_tag_t tag; /* should be first for our bsearch to work */
+ unsigned int index[2]; /* GSUB/GPOS */
+ unsigned int stage[2]; /* GSUB/GPOS */
+ unsigned int shift;
+ hb_mask_t mask;
+ hb_mask_t _1_mask; /* mask for value=1, for quick access */
+ unsigned int needs_fallback : 1;
+ unsigned int auto_zwj : 1;
+
+ static int cmp (const feature_map_t *a, const feature_map_t *b)
+ { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
+ };
+
+ struct lookup_map_t {
+ unsigned short index;
+ unsigned short auto_zwj : 1;
+ hb_mask_t mask;
+
+ static int cmp (const lookup_map_t *a, const lookup_map_t *b)
+ { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
+ };
+
+ typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
+
+ struct stage_map_t {
+ unsigned int last_lookup; /* Cumulative */
+ pause_func_t pause_func;
+ };
+
+
+ hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
+
+ inline hb_mask_t get_global_mask (void) const { return global_mask; }
+
+ inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
+ if (shift) *shift = map ? map->shift : 0;
+ return map ? map->mask : 0;
+ }
+
+ inline bool needs_fallback (hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
+ return map ? map->needs_fallback : false;
+ }
+
+ inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
+ return map ? map->_1_mask : 0;
+ }
+
+ inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
+ return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
+ }
+
+ inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
+ return map ? map->stage[table_index] : (unsigned int) -1;
+ }
+
+ inline void get_stage_lookups (unsigned int table_index, unsigned int stage,
+ const struct lookup_map_t **plookups, unsigned int *lookup_count) const {
+ if (unlikely (stage == (unsigned int) -1)) {
+ *plookups = NULL;
+ *lookup_count = 0;
+ return;
+ }
+ assert (stage <= stages[table_index].len);
+ unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0;
+ unsigned int end = stage < stages[table_index].len ? stages[table_index][stage].last_lookup : lookups[table_index].len;
+ *plookups = &lookups[table_index][start];
+ *lookup_count = end - start;
+ }
+
+ HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
+ template <typename Proxy>
+ HB_INTERNAL inline void apply (const Proxy &proxy,
+ const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+ HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+ HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+
+ inline void finish (void) {
+ features.finish ();
+ for (unsigned int table_index = 0; table_index < 2; table_index++)
+ {
+ lookups[table_index].finish ();
+ stages[table_index].finish ();
+ }
+ }
+
+ public:
+ hb_tag_t chosen_script[2];
+ bool found_script[2];
+
+ private:
+
+ HB_INTERNAL void add_lookups (hb_face_t *face,
+ unsigned int table_index,
+ unsigned int feature_index,
+ hb_mask_t mask,
+ bool auto_zwj);
+
+ hb_mask_t global_mask;
+
+ hb_prealloced_array_t<feature_map_t, 8> features;
+ hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
+ hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
+};
+
+enum hb_ot_map_feature_flags_t {
+ F_NONE = 0x0000,
+ F_GLOBAL = 0x0001,
+ F_HAS_FALLBACK = 0x0002,
+ F_MANUAL_ZWJ = 0x0004
+};
+/* Macro version for where const is desired. */
+#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
+inline hb_ot_map_feature_flags_t
+operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
+inline hb_ot_map_feature_flags_t
+operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
+inline hb_ot_map_feature_flags_t
+operator ~ (hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
+inline hb_ot_map_feature_flags_t&
+operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
+{ l = l | r; return l; }
+inline hb_ot_map_feature_flags_t&
+operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
+{ l = l & r; return l; }
+
+
+struct hb_ot_map_builder_t
+{
+ public:
+
+ HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
+ const hb_segment_properties_t *props_);
+
+ HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
+ hb_ot_map_feature_flags_t flags);
+
+ inline void add_global_bool_feature (hb_tag_t tag)
+ { add_feature (tag, 1, F_GLOBAL); }
+
+ inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
+ { add_pause (0, pause_func); }
+ inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
+ { add_pause (1, pause_func); }
+
+ HB_INTERNAL void compile (struct hb_ot_map_t &m);
+
+ inline void finish (void) {
+ feature_infos.finish ();
+ for (unsigned int table_index = 0; table_index < 2; table_index++)
+ {
+ stages[table_index].finish ();
+ }
+ }
+
+ private:
+
+ struct feature_info_t {
+ hb_tag_t tag;
+ unsigned int seq; /* sequence#, used for stable sorting only */
+ unsigned int max_value;
+ hb_ot_map_feature_flags_t flags;
+ unsigned int default_value; /* for non-global features, what should the unset glyphs take */
+ unsigned int stage[2]; /* GSUB/GPOS */
+
+ static int cmp (const feature_info_t *a, const feature_info_t *b)
+ { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); }
+ };
+
+ struct stage_info_t {
+ unsigned int index;
+ hb_ot_map_t::pause_func_t pause_func;
+ };
+
+ HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func);
+
+ public:
+
+ hb_face_t *face;
+ hb_segment_properties_t props;
+
+ hb_tag_t chosen_script[2];
+ bool found_script[2];
+ unsigned int script_index[2], language_index[2];
+
+ private:
+
+ unsigned int current_stage[2]; /* GSUB/GPOS */
+ hb_prealloced_array_t<feature_info_t, 32> feature_infos;
+ hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
+};
+
+
+
+#endif /* HB_OT_MAP_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
new file mode 100644
index 0000000000..43856fa37e
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
@@ -0,0 +1,275 @@
+/*
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2010,2011,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-map-private.hh"
+
+#include "hb-ot-layout-private.hh"
+
+
+void
+hb_ot_map_t::add_lookups (hb_face_t *face,
+ unsigned int table_index,
+ unsigned int feature_index,
+ hb_mask_t mask,
+ bool auto_zwj)
+{
+ unsigned int lookup_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (lookup_indices);
+ hb_ot_layout_feature_get_lookups (face,
+ table_tags[table_index],
+ feature_index,
+ offset, &len,
+ lookup_indices);
+
+ for (unsigned int i = 0; i < len; i++) {
+ hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push ();
+ if (unlikely (!lookup))
+ return;
+ lookup->mask = mask;
+ lookup->index = lookup_indices[i];
+ lookup->auto_zwj = auto_zwj;
+ }
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (lookup_indices));
+}
+
+hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
+ const hb_segment_properties_t *props_)
+{
+ memset (this, 0, sizeof (*this));
+
+ face = face_;
+ props = *props_;
+
+
+ /* Fetch script/language indices for GSUB/GPOS. We need these later to skip
+ * features not available in either table and not waste precious bits for them. */
+
+ hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
+ hb_tag_t language_tag;
+
+ hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
+ language_tag = hb_ot_tag_from_language (props.language);
+
+ for (unsigned int table_index = 0; table_index < 2; table_index++) {
+ hb_tag_t table_tag = table_tags[table_index];
+ found_script[table_index] = hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
+ hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
+ }
+}
+
+void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
+ hb_ot_map_feature_flags_t flags)
+{
+ feature_info_t *info = feature_infos.push();
+ if (unlikely (!info)) return;
+ info->tag = tag;
+ info->seq = feature_infos.len;
+ info->max_value = value;
+ info->flags = flags;
+ info->default_value = (flags & F_GLOBAL) ? value : 0;
+ info->stage[0] = current_stage[0];
+ info->stage[1] = current_stage[1];
+}
+
+
+void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
+{
+ for (unsigned int i = 0; i < lookups[table_index].len; i++)
+ hb_set_add (lookups_out, lookups[table_index][i].index);
+}
+
+void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
+{
+ stage_info_t *s = stages[table_index].push ();
+ if (likely (s)) {
+ s->index = current_stage[table_index];
+ s->pause_func = pause_func;
+ }
+
+ current_stage[table_index]++;
+}
+
+void
+hb_ot_map_builder_t::compile (hb_ot_map_t &m)
+{
+ m.global_mask = 1;
+
+ for (unsigned int table_index = 0; table_index < 2; table_index++) {
+ m.chosen_script[table_index] = chosen_script[table_index];
+ m.found_script[table_index] = found_script[table_index];
+ }
+
+ if (!feature_infos.len)
+ return;
+
+ /* Sort features and merge duplicates */
+ {
+ feature_infos.sort ();
+ unsigned int j = 0;
+ for (unsigned int i = 1; i < feature_infos.len; i++)
+ if (feature_infos[i].tag != feature_infos[j].tag)
+ feature_infos[++j] = feature_infos[i];
+ else {
+ if (feature_infos[i].flags & F_GLOBAL) {
+ feature_infos[j].flags |= F_GLOBAL;
+ feature_infos[j].max_value = feature_infos[i].max_value;
+ feature_infos[j].default_value = feature_infos[i].default_value;
+ } else {
+ feature_infos[j].flags &= ~F_GLOBAL;
+ feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
+ /* Inherit default_value from j */
+ }
+ feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
+ feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
+ feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
+ }
+ feature_infos.shrink (j + 1);
+ }
+
+
+ /* Allocate bits now */
+ unsigned int next_bit = 1;
+ for (unsigned int i = 0; i < feature_infos.len; i++) {
+ const feature_info_t *info = &feature_infos[i];
+
+ unsigned int bits_needed;
+
+ if ((info->flags & F_GLOBAL) && info->max_value == 1)
+ /* Uses the global bit */
+ bits_needed = 0;
+ else
+ bits_needed = _hb_bit_storage (info->max_value);
+
+ if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
+ continue; /* Feature disabled, or not enough bits. */
+
+
+ bool found = false;
+ unsigned int feature_index[2];
+ for (unsigned int table_index = 0; table_index < 2; table_index++)
+ found |= hb_ot_layout_language_find_feature (face,
+ table_tags[table_index],
+ script_index[table_index],
+ language_index[table_index],
+ info->tag,
+ &feature_index[table_index]);
+ if (!found && !(info->flags & F_HAS_FALLBACK))
+ continue;
+
+
+ hb_ot_map_t::feature_map_t *map = m.features.push ();
+ if (unlikely (!map))
+ break;
+
+ map->tag = info->tag;
+ map->index[0] = feature_index[0];
+ map->index[1] = feature_index[1];
+ map->stage[0] = info->stage[0];
+ map->stage[1] = info->stage[1];
+ map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
+ if ((info->flags & F_GLOBAL) && info->max_value == 1) {
+ /* Uses the global bit */
+ map->shift = 0;
+ map->mask = 1;
+ } else {
+ map->shift = next_bit;
+ map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
+ next_bit += bits_needed;
+ m.global_mask |= (info->default_value << map->shift) & map->mask;
+ }
+ map->_1_mask = (1 << map->shift) & map->mask;
+ map->needs_fallback = !found;
+
+ }
+ feature_infos.shrink (0); /* Done with these */
+
+
+ add_gsub_pause (NULL);
+ add_gpos_pause (NULL);
+
+ for (unsigned int table_index = 0; table_index < 2; table_index++) {
+ hb_tag_t table_tag = table_tags[table_index];
+
+ /* Collect lookup indices for features */
+
+ unsigned int required_feature_index;
+ if (hb_ot_layout_language_get_required_feature_index (face,
+ table_tag,
+ script_index[table_index],
+ language_index[table_index],
+ &required_feature_index))
+ m.add_lookups (face, table_index, required_feature_index, 1, true);
+
+ unsigned int stage_index = 0;
+ unsigned int last_num_lookups = 0;
+ for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
+ {
+ for (unsigned i = 0; i < m.features.len; i++)
+ if (m.features[i].stage[table_index] == stage)
+ m.add_lookups (face, table_index,
+ m.features[i].index[table_index],
+ m.features[i].mask,
+ m.features[i].auto_zwj);
+
+ /* Sort lookups and merge duplicates */
+ if (last_num_lookups < m.lookups[table_index].len)
+ {
+ m.lookups[table_index].sort (last_num_lookups, m.lookups[table_index].len);
+
+ unsigned int j = last_num_lookups;
+ for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++)
+ if (m.lookups[table_index][i].index != m.lookups[table_index][j].index)
+ m.lookups[table_index][++j] = m.lookups[table_index][i];
+ else
+ {
+ m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask;
+ m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj;
+ }
+ m.lookups[table_index].shrink (j + 1);
+ }
+
+ last_num_lookups = m.lookups[table_index].len;
+
+ if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) {
+ hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();
+ if (likely (stage_map)) {
+ stage_map->last_lookup = last_num_lookups;
+ stage_map->pause_func = stages[table_index][stage_index].pause_func;
+ }
+
+ stage_index++;
+ }
+ }
+ }
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
new file mode 100644
index 0000000000..0ce3ebcc2a
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_MAXP_TABLE_HH
+#define HB_OT_MAXP_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * maxp -- The Maximum Profile Table
+ */
+
+#define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
+
+struct maxp
+{
+ static const hb_tag_t Tag = HB_OT_TAG_maxp;
+
+ inline unsigned int get_num_glyphs (void) const {
+ return numGlyphs;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) &&
+ likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000)));
+ }
+
+ /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
+ protected:
+ FixedVersion version; /* Version of the maxp table (0.5 or 1.0),
+ * 0x00005000 or 0x00010000. */
+ USHORT numGlyphs; /* The number of glyphs in the font. */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_MAXP_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
new file mode 100644
index 0000000000..e36b0f7c97
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_NAME_TABLE_HH
+#define HB_OT_NAME_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * name -- The Naming Table
+ */
+
+#define HB_OT_TAG_name HB_TAG('n','a','m','e')
+
+
+struct NameRecord
+{
+ static int cmp (const NameRecord *a, const NameRecord *b)
+ {
+ int ret;
+ ret = b->platformID.cmp (a->platformID);
+ if (ret) return ret;
+ ret = b->encodingID.cmp (a->encodingID);
+ if (ret) return ret;
+ ret = b->languageID.cmp (a->languageID);
+ if (ret) return ret;
+ ret = b->nameID.cmp (a->nameID);
+ if (ret) return ret;
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+ TRACE_SANITIZE (this);
+ /* We can check from base all the way up to the end of string... */
+ return TRACE_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
+ }
+
+ USHORT platformID; /* Platform ID. */
+ USHORT encodingID; /* Platform-specific encoding ID. */
+ USHORT languageID; /* Language ID. */
+ USHORT nameID; /* Name ID. */
+ USHORT length; /* String length (in bytes). */
+ USHORT offset; /* String offset from start of storage area (in bytes). */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct name
+{
+ static const hb_tag_t Tag = HB_OT_TAG_name;
+
+ inline unsigned int get_name (unsigned int platform_id,
+ unsigned int encoding_id,
+ unsigned int language_id,
+ unsigned int name_id,
+ void *buffer,
+ unsigned int buffer_length) const
+ {
+ NameRecord key;
+ key.platformID.set (platform_id);
+ key.encodingID.set (encoding_id);
+ key.languageID.set (language_id);
+ key.nameID.set (name_id);
+ NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
+
+ if (!match)
+ return 0;
+
+ unsigned int length = MIN (buffer_length, (unsigned int) match->length);
+ memcpy (buffer, (char *) this + stringOffset + match->offset, length);
+ return length;
+ }
+
+ inline unsigned int get_size (void) const
+ { return min_size + count * nameRecord[0].min_size; }
+
+ inline bool sanitize_records (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ char *string_pool = (char *) this + stringOffset;
+ unsigned int _count = count;
+ for (unsigned int i = 0; i < _count; i++)
+ if (!nameRecord[i].sanitize (c, string_pool)) return TRACE_RETURN (false);
+ return TRACE_RETURN (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) &&
+ likely (format == 0 || format == 1) &&
+ c->check_array (nameRecord, nameRecord[0].static_size, count) &&
+ sanitize_records (c));
+ }
+
+ /* We only implement format 0 for now. */
+ USHORT format; /* Format selector (=0/1). */
+ USHORT count; /* Number of name records. */
+ Offset stringOffset; /* Offset to start of string storage (from start of table). */
+ NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
+ public:
+ DEFINE_SIZE_ARRAY (6, nameRecord);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_NAME_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
new file mode 100644
index 0000000000..6b2b87e3f2
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -0,0 +1,260 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-layout-gsub-table.hh"
+
+
+static const hb_tag_t arabic_fallback_features[] =
+{
+ HB_TAG('i','n','i','t'),
+ HB_TAG('m','e','d','i'),
+ HB_TAG('f','i','n','a'),
+ HB_TAG('i','s','o','l'),
+ HB_TAG('r','l','i','g'),
+};
+
+/* Same order as the fallback feature array */
+enum {
+ FALLBACK_INIT,
+ FALLBACK_MEDI,
+ FALLBACK_FINA,
+ FALLBACK_ISOL,
+ FALLBACK_RLIG,
+ ARABIC_NUM_FALLBACK_FEATURES
+};
+
+static OT::SubstLookup *
+arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font,
+ unsigned int feature_index)
+{
+ OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+ OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+ unsigned int num_glyphs = 0;
+
+ /* Populate arrays */
+ for (hb_codepoint_t u = SHAPING_TABLE_FIRST; u < SHAPING_TABLE_LAST + 1; u++)
+ {
+ hb_codepoint_t s = shaping_table[u - SHAPING_TABLE_FIRST][feature_index];
+ hb_codepoint_t u_glyph, s_glyph;
+
+ if (!s ||
+ !hb_font_get_glyph (font, u, 0, &u_glyph) ||
+ !hb_font_get_glyph (font, s, 0, &s_glyph) ||
+ u_glyph == s_glyph ||
+ u_glyph > 0xFFFF || s_glyph > 0xFFFF)
+ continue;
+
+ glyphs[num_glyphs].set (u_glyph);
+ substitutes[num_glyphs].set (s_glyph);
+
+ num_glyphs++;
+ }
+
+ /* Bubble-sort!
+ * May not be good-enough for presidential candidate interviews, but good-enough for us... */
+ hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
+
+ OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
+ OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
+
+ /* Each glyph takes four bytes max, and there's some overhead. */
+ char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
+ OT::hb_serialize_context_t c (buf, sizeof (buf));
+ OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
+ bool ret = lookup->serialize_single (&c,
+ OT::LookupFlag::IgnoreMarks,
+ glyphs_supplier,
+ substitutes_supplier,
+ num_glyphs);
+ c.end_serialize ();
+ /* TODO sanitize the results? */
+
+ return ret ? c.copy<OT::SubstLookup> () : NULL;
+}
+
+static OT::SubstLookup *
+arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font)
+{
+ OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
+ unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
+ unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
+ unsigned int num_first_glyphs = 0;
+
+ /* We know that all our ligatures are 2-component */
+ OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
+ unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
+ OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
+ unsigned int num_ligatures = 0;
+
+ /* Populate arrays */
+
+ /* Sort out the first-glyphs */
+ for (unsigned int first_glyph_idx = 0; first_glyph_idx < ARRAY_LENGTH (first_glyphs); first_glyph_idx++)
+ {
+ hb_codepoint_t first_u = ligature_table[first_glyph_idx].first;
+ hb_codepoint_t first_glyph;
+ if (!hb_font_get_glyph (font, first_u, 0, &first_glyph))
+ continue;
+ first_glyphs[num_first_glyphs].set (first_glyph);
+ ligature_per_first_glyph_count_list[num_first_glyphs] = 0;
+ first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
+ num_first_glyphs++;
+ }
+ hb_bubble_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]);
+
+ /* Now that the first-glyphs are sorted, walk again, populate ligatures. */
+ for (unsigned int i = 0; i < num_first_glyphs; i++)
+ {
+ unsigned int first_glyph_idx = first_glyphs_indirection[i];
+
+ for (unsigned int second_glyph_idx = 0; second_glyph_idx < ARRAY_LENGTH (ligature_table[0].ligatures); second_glyph_idx++)
+ {
+ hb_codepoint_t second_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].second;
+ hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].ligature;
+ hb_codepoint_t second_glyph, ligature_glyph;
+ if (!second_u ||
+ !hb_font_get_glyph (font, second_u, 0, &second_glyph) ||
+ !hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
+ continue;
+
+ ligature_per_first_glyph_count_list[i]++;
+
+ ligature_list[num_ligatures].set (ligature_glyph);
+ component_count_list[num_ligatures] = 2;
+ component_list[num_ligatures].set (second_glyph);
+ num_ligatures++;
+ }
+ }
+
+ OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
+ OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
+ OT::Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
+ OT::Supplier<unsigned int > component_count_supplier (component_count_list, num_ligatures);
+ OT::Supplier<OT::GlyphID> component_supplier (component_list, num_ligatures);
+
+ /* 16 bytes per ligature ought to be enough... */
+ char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
+ OT::hb_serialize_context_t c (buf, sizeof (buf));
+ OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
+ bool ret = lookup->serialize_ligature (&c,
+ OT::LookupFlag::IgnoreMarks,
+ first_glyphs_supplier,
+ ligature_per_first_glyph_count_supplier,
+ num_first_glyphs,
+ ligatures_supplier,
+ component_count_supplier,
+ component_supplier);
+
+ c.end_serialize ();
+ /* TODO sanitize the results? */
+
+ return ret ? c.copy<OT::SubstLookup> () : NULL;
+}
+
+static OT::SubstLookup *
+arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ unsigned int feature_index)
+{
+ if (feature_index < 4)
+ return arabic_fallback_synthesize_lookup_single (plan, font, feature_index);
+ else
+ return arabic_fallback_synthesize_lookup_ligature (plan, font);
+}
+
+struct arabic_fallback_plan_t
+{
+ ASSERT_POD ();
+
+ hb_mask_t mask_array[ARABIC_NUM_FALLBACK_FEATURES];
+ OT::SubstLookup *lookup_array[ARABIC_NUM_FALLBACK_FEATURES];
+ hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_NUM_FALLBACK_FEATURES];
+};
+
+static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
+
+static arabic_fallback_plan_t *
+arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font)
+{
+ arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
+ if (unlikely (!fallback_plan))
+ return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
+
+ for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
+ {
+ fallback_plan->mask_array[i] = plan->map.get_1_mask (arabic_fallback_features[i]);
+ if (fallback_plan->mask_array[i]) {
+ fallback_plan->lookup_array[i] = arabic_fallback_synthesize_lookup (plan, font, i);
+ if (fallback_plan->lookup_array[i])
+ fallback_plan->accel_array[i].init (*fallback_plan->lookup_array[i]);
+ }
+ }
+
+ return fallback_plan;
+}
+
+static void
+arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
+{
+ if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
+ return;
+
+ for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
+ if (fallback_plan->lookup_array[i])
+ {
+ fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]);
+ free (fallback_plan->lookup_array[i]);
+ }
+
+ free (fallback_plan);
+}
+
+static void
+arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ OT::hb_apply_context_t c (0, font, buffer);
+ for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
+ if (fallback_plan->lookup_array[i]) {
+ c.set_lookup_mask (fallback_plan->mask_array[i]);
+ hb_ot_layout_substitute_lookup (&c,
+ *fallback_plan->lookup_array[i],
+ fallback_plan->accel_array[i]);
+ }
+}
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
new file mode 100644
index 0000000000..730a275bf0
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
@@ -0,0 +1,942 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt
+ *
+ * on files with these headers:
+ *
+ * # ArabicShaping-6.2.0.txt
+ * # Date: 2012-05-15, 21:05:00 GMT [KW]
+ * UnicodeData.txt does not have a header.
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+
+
+static const uint8_t joining_table[] =
+{
+
+ /* Arabic Characters */
+
+ JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0604; ARABIC SIGN SAMVAT; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 0605 */
+ JOINING_TYPE_X, /* 0606 */
+ JOINING_TYPE_X, /* 0607 */
+ JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 0609 */
+ JOINING_TYPE_X, /* 060A */
+ JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 060C */
+ JOINING_TYPE_X, /* 060D */
+ JOINING_TYPE_X, /* 060E */
+ JOINING_TYPE_X, /* 060F */
+ JOINING_TYPE_X, /* 0610 */
+ JOINING_TYPE_X, /* 0611 */
+ JOINING_TYPE_X, /* 0612 */
+ JOINING_TYPE_X, /* 0613 */
+ JOINING_TYPE_X, /* 0614 */
+ JOINING_TYPE_X, /* 0615 */
+ JOINING_TYPE_X, /* 0616 */
+ JOINING_TYPE_X, /* 0617 */
+ JOINING_TYPE_X, /* 0618 */
+ JOINING_TYPE_X, /* 0619 */
+ JOINING_TYPE_X, /* 061A */
+ JOINING_TYPE_X, /* 061B */
+ JOINING_TYPE_X, /* 061C */
+ JOINING_TYPE_X, /* 061D */
+ JOINING_TYPE_X, /* 061E */
+ JOINING_TYPE_X, /* 061F */
+ JOINING_TYPE_D, /* 0620; DOTLESS YEH WITH SEPARATE RING BELOW; D; YEH */
+ JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
+ JOINING_TYPE_R, /* 0622; ALEF WITH MADDA ABOVE; R; ALEF */
+ JOINING_TYPE_R, /* 0623; ALEF WITH HAMZA ABOVE; R; ALEF */
+ JOINING_TYPE_R, /* 0624; WAW WITH HAMZA ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 0625; ALEF WITH HAMZA BELOW; R; ALEF */
+ JOINING_TYPE_D, /* 0626; DOTLESS YEH WITH HAMZA ABOVE; D; YEH */
+ JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */
+ JOINING_TYPE_D, /* 0628; BEH; D; BEH */
+ JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */
+ JOINING_TYPE_D, /* 062A; DOTLESS BEH WITH 2 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 062B; DOTLESS BEH WITH 3 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 062C; HAH WITH DOT BELOW; D; HAH */
+ JOINING_TYPE_D, /* 062D; HAH; D; HAH */
+ JOINING_TYPE_D, /* 062E; HAH WITH DOT ABOVE; D; HAH */
+ JOINING_TYPE_R, /* 062F; DAL; R; DAL */
+ JOINING_TYPE_R, /* 0630; DAL WITH DOT ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 0631; REH; R; REH */
+ JOINING_TYPE_R, /* 0632; REH WITH DOT ABOVE; R; REH */
+ JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */
+ JOINING_TYPE_D, /* 0634; SEEN WITH 3 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 0635; SAD; D; SAD */
+ JOINING_TYPE_D, /* 0636; SAD WITH DOT ABOVE; D; SAD */
+ JOINING_TYPE_D, /* 0637; TAH; D; TAH */
+ JOINING_TYPE_D, /* 0638; TAH WITH DOT ABOVE; D; TAH */
+ JOINING_TYPE_D, /* 0639; AIN; D; AIN */
+ JOINING_TYPE_D, /* 063A; AIN WITH DOT ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */
+ JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */
+ JOINING_TYPE_D, /* 0641; FEH; D; FEH */
+ JOINING_TYPE_D, /* 0642; QAF; D; QAF */
+ JOINING_TYPE_D, /* 0643; KAF; D; KAF */
+ JOINING_TYPE_D, /* 0644; LAM; D; LAM */
+ JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */
+ JOINING_TYPE_D, /* 0646; NOON; D; NOON */
+ JOINING_TYPE_D, /* 0647; HEH; D; HEH */
+ JOINING_TYPE_R, /* 0648; WAW; R; WAW */
+ JOINING_TYPE_D, /* 0649; DOTLESS YEH; D; YEH */
+ JOINING_TYPE_D, /* 064A; YEH; D; YEH */
+ JOINING_TYPE_X, /* 064B */
+ JOINING_TYPE_X, /* 064C */
+ JOINING_TYPE_X, /* 064D */
+ JOINING_TYPE_X, /* 064E */
+ JOINING_TYPE_X, /* 064F */
+ JOINING_TYPE_X, /* 0650 */
+ JOINING_TYPE_X, /* 0651 */
+ JOINING_TYPE_X, /* 0652 */
+ JOINING_TYPE_X, /* 0653 */
+ JOINING_TYPE_X, /* 0654 */
+ JOINING_TYPE_X, /* 0655 */
+ JOINING_TYPE_X, /* 0656 */
+ JOINING_TYPE_X, /* 0657 */
+ JOINING_TYPE_X, /* 0658 */
+ JOINING_TYPE_X, /* 0659 */
+ JOINING_TYPE_X, /* 065A */
+ JOINING_TYPE_X, /* 065B */
+ JOINING_TYPE_X, /* 065C */
+ JOINING_TYPE_X, /* 065D */
+ JOINING_TYPE_X, /* 065E */
+ JOINING_TYPE_X, /* 065F */
+ JOINING_TYPE_X, /* 0660 */
+ JOINING_TYPE_X, /* 0661 */
+ JOINING_TYPE_X, /* 0662 */
+ JOINING_TYPE_X, /* 0663 */
+ JOINING_TYPE_X, /* 0664 */
+ JOINING_TYPE_X, /* 0665 */
+ JOINING_TYPE_X, /* 0666 */
+ JOINING_TYPE_X, /* 0667 */
+ JOINING_TYPE_X, /* 0668 */
+ JOINING_TYPE_X, /* 0669 */
+ JOINING_TYPE_X, /* 066A */
+ JOINING_TYPE_X, /* 066B */
+ JOINING_TYPE_X, /* 066C */
+ JOINING_TYPE_X, /* 066D */
+ JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */
+ JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */
+ JOINING_TYPE_X, /* 0670 */
+ JOINING_TYPE_R, /* 0671; ALEF WITH WASLA ABOVE; R; ALEF */
+ JOINING_TYPE_R, /* 0672; ALEF WITH WAVY HAMZA ABOVE; R; ALEF */
+ JOINING_TYPE_R, /* 0673; ALEF WITH WAVY HAMZA BELOW; R; ALEF */
+ JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */
+ JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */
+ JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 0678; HIGH HAMZA DOTLESS YEH; D; YEH */
+ JOINING_TYPE_D, /* 0679; DOTLESS BEH WITH TAH ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 067A; DOTLESS BEH WITH VERTICAL 2 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 067B; DOTLESS BEH WITH VERTICAL 2 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 067C; DOTLESS BEH WITH ATTACHED RING BELOW AND 2 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 067D; DOTLESS BEH WITH INVERTED 3 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 067E; DOTLESS BEH WITH 3 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 067F; DOTLESS BEH WITH 4 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0680; DOTLESS BEH WITH 4 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0681; HAH WITH HAMZA ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0682; HAH WITH VERTICAL 2 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0683; HAH WITH 2 DOTS BELOW; D; HAH */
+ JOINING_TYPE_D, /* 0684; HAH WITH VERTICAL 2 DOTS BELOW; D; HAH */
+ JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0686; HAH WITH 3 DOTS BELOW; D; HAH */
+ JOINING_TYPE_D, /* 0687; HAH WITH 4 DOTS BELOW; D; HAH */
+ JOINING_TYPE_R, /* 0688; DAL WITH TAH ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 0689; DAL WITH ATTACHED RING BELOW; R; DAL */
+ JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */
+ JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND TAH ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */
+ JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 068F; DAL WITH INVERTED 3 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 0691; REH WITH TAH ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0692; REH WITH V ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0693; REH WITH ATTACHED RING BELOW; R; REH */
+ JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */
+ JOINING_TYPE_R, /* 0695; REH WITH V BELOW; R; REH */
+ JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT WITHIN; R; REH */
+ JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */
+ JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */
+ JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */
+ JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */
+ JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */
+ JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */
+ JOINING_TYPE_D, /* 06A2; DOTLESS FEH WITH DOT BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A4; DOTLESS FEH WITH 3 DOTS ABOVE; D; FEH */
+ JOINING_TYPE_D, /* 06A5; DOTLESS FEH WITH 3 DOTS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A6; DOTLESS FEH WITH 4 DOTS ABOVE; D; FEH */
+ JOINING_TYPE_D, /* 06A7; DOTLESS QAF WITH DOT ABOVE; D; QAF */
+ JOINING_TYPE_D, /* 06A8; DOTLESS QAF WITH 3 DOTS ABOVE; D; QAF */
+ JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */
+ JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */
+ JOINING_TYPE_D, /* 06AB; KEHEH WITH ATTACHED RING BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */
+ JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */
+ JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */
+ JOINING_TYPE_D, /* 06AF; GAF; D; GAF */
+ JOINING_TYPE_D, /* 06B0; GAF WITH ATTACHED RING BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06B3; GAF WITH VERTICAL 2 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 06B5; LAM WITH V ABOVE; D; LAM */
+ JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */
+ JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */
+ JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */
+ JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */
+ JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */
+ JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH TAH ABOVE; D; NOON */
+ JOINING_TYPE_D, /* 06BC; NOON WITH ATTACHED RING BELOW; D; NOON */
+ JOINING_TYPE_D, /* 06BD; NYA; D; NYA */
+ JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */
+ JOINING_TYPE_D, /* 06BF; HAH WITH 3 DOTS BELOW AND DOT ABOVE; D; HAH */
+ JOINING_TYPE_R, /* 06C0; DOTLESS TEH MARBUTA WITH HAMZA ABOVE; R; TEH MARBUTA */
+ JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
+ JOINING_TYPE_D, /* 06C2; HEH GOAL WITH HAMZA ABOVE; D; HEH GOAL */
+ JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
+ JOINING_TYPE_R, /* 06C4; WAW WITH ATTACHED RING WITHIN; R; WAW */
+ JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
+ JOINING_TYPE_R, /* 06C6; WAW WITH V ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED V ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */
+ JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */
+ JOINING_TYPE_D, /* 06CE; FARSI YEH WITH V ABOVE; D; FARSI YEH */
+ JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 06D0; DOTLESS YEH WITH VERTICAL 2 DOTS BELOW; D; YEH */
+ JOINING_TYPE_D, /* 06D1; DOTLESS YEH WITH 3 DOTS BELOW; D; YEH */
+ JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */
+ JOINING_TYPE_R, /* 06D3; YEH BARREE WITH HAMZA ABOVE; R; YEH BARREE */
+ JOINING_TYPE_X, /* 06D4 */
+ JOINING_TYPE_R, /* 06D5; DOTLESS TEH MARBUTA; R; TEH MARBUTA */
+ JOINING_TYPE_X, /* 06D6 */
+ JOINING_TYPE_X, /* 06D7 */
+ JOINING_TYPE_X, /* 06D8 */
+ JOINING_TYPE_X, /* 06D9 */
+ JOINING_TYPE_X, /* 06DA */
+ JOINING_TYPE_X, /* 06DB */
+ JOINING_TYPE_X, /* 06DC */
+ JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 06DE */
+ JOINING_TYPE_X, /* 06DF */
+ JOINING_TYPE_X, /* 06E0 */
+ JOINING_TYPE_X, /* 06E1 */
+ JOINING_TYPE_X, /* 06E2 */
+ JOINING_TYPE_X, /* 06E3 */
+ JOINING_TYPE_X, /* 06E4 */
+ JOINING_TYPE_X, /* 06E5 */
+ JOINING_TYPE_X, /* 06E6 */
+ JOINING_TYPE_X, /* 06E7 */
+ JOINING_TYPE_X, /* 06E8 */
+ JOINING_TYPE_X, /* 06E9 */
+ JOINING_TYPE_X, /* 06EA */
+ JOINING_TYPE_X, /* 06EB */
+ JOINING_TYPE_X, /* 06EC */
+ JOINING_TYPE_X, /* 06ED */
+ JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V ABOVE; R; REH */
+ JOINING_TYPE_X, /* 06F0 */
+ JOINING_TYPE_X, /* 06F1 */
+ JOINING_TYPE_X, /* 06F2 */
+ JOINING_TYPE_X, /* 06F3 */
+ JOINING_TYPE_X, /* 06F4 */
+ JOINING_TYPE_X, /* 06F5 */
+ JOINING_TYPE_X, /* 06F6 */
+ JOINING_TYPE_X, /* 06F7 */
+ JOINING_TYPE_X, /* 06F8 */
+ JOINING_TYPE_X, /* 06F9 */
+ JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 06FB; SAD WITH DOT BELOW AND DOT ABOVE; D; SAD */
+ JOINING_TYPE_D, /* 06FC; AIN WITH DOT BELOW AND DOT ABOVE; D; AIN */
+ JOINING_TYPE_X, /* 06FD */
+ JOINING_TYPE_X, /* 06FE */
+ JOINING_TYPE_D, /* 06FF; KNOTTED HEH WITH INVERTED V ABOVE; D; KNOTTED HEH */
+
+ /* Syriac Characters */
+
+ JOINING_TYPE_X, /* 0700 */
+ JOINING_TYPE_X, /* 0701 */
+ JOINING_TYPE_X, /* 0702 */
+ JOINING_TYPE_X, /* 0703 */
+ JOINING_TYPE_X, /* 0704 */
+ JOINING_TYPE_X, /* 0705 */
+ JOINING_TYPE_X, /* 0706 */
+ JOINING_TYPE_X, /* 0707 */
+ JOINING_TYPE_X, /* 0708 */
+ JOINING_TYPE_X, /* 0709 */
+ JOINING_TYPE_X, /* 070A */
+ JOINING_TYPE_X, /* 070B */
+ JOINING_TYPE_X, /* 070C */
+ JOINING_TYPE_X, /* 070D */
+ JOINING_TYPE_X, /* 070E */
+ JOINING_TYPE_X, /* 070F */
+ JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */
+ JOINING_TYPE_X, /* 0711 */
+ JOINING_TYPE_D, /* 0712; BETH; D; BETH */
+ JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */
+ JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */
+ JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */
+ JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */
+ JOINING_TYPE_R, /* 0717; HE; R; HE */
+ JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */
+ JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */
+ JOINING_TYPE_D, /* 071A; HETH; D; HETH */
+ JOINING_TYPE_D, /* 071B; TETH; D; TETH */
+ JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */
+ JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */
+ JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */
+ JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */
+ JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */
+ JOINING_TYPE_D, /* 0721; MIM; D; MIM */
+ JOINING_TYPE_D, /* 0722; NUN; D; NUN */
+ JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */
+ JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */
+ JOINING_TYPE_D, /* 0725; E; D; E */
+ JOINING_TYPE_D, /* 0726; PE; D; PE */
+ JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */
+ JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */
+ JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */
+ JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */
+ JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */
+ JOINING_TYPE_R, /* 072C; TAW; R; TAW */
+ JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */
+ JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */
+ JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */
+ JOINING_TYPE_X, /* 0730 */
+ JOINING_TYPE_X, /* 0731 */
+ JOINING_TYPE_X, /* 0732 */
+ JOINING_TYPE_X, /* 0733 */
+ JOINING_TYPE_X, /* 0734 */
+ JOINING_TYPE_X, /* 0735 */
+ JOINING_TYPE_X, /* 0736 */
+ JOINING_TYPE_X, /* 0737 */
+ JOINING_TYPE_X, /* 0738 */
+ JOINING_TYPE_X, /* 0739 */
+ JOINING_TYPE_X, /* 073A */
+ JOINING_TYPE_X, /* 073B */
+ JOINING_TYPE_X, /* 073C */
+ JOINING_TYPE_X, /* 073D */
+ JOINING_TYPE_X, /* 073E */
+ JOINING_TYPE_X, /* 073F */
+ JOINING_TYPE_X, /* 0740 */
+ JOINING_TYPE_X, /* 0741 */
+ JOINING_TYPE_X, /* 0742 */
+ JOINING_TYPE_X, /* 0743 */
+ JOINING_TYPE_X, /* 0744 */
+ JOINING_TYPE_X, /* 0745 */
+ JOINING_TYPE_X, /* 0746 */
+ JOINING_TYPE_X, /* 0747 */
+ JOINING_TYPE_X, /* 0748 */
+ JOINING_TYPE_X, /* 0749 */
+ JOINING_TYPE_X, /* 074A */
+ JOINING_TYPE_X, /* 074B */
+ JOINING_TYPE_X, /* 074C */
+ JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */
+ JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */
+ JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */
+
+ /* Arabic Supplement Characters */
+
+ JOINING_TYPE_D, /* 0750; DOTLESS BEH WITH HORIZONTAL 3 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0751; BEH WITH 3 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0752; DOTLESS BEH WITH INVERTED 3 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0753; DOTLESS BEH WITH INVERTED 3 DOTS BELOW AND 2 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0754; DOTLESS BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0755; DOTLESS BEH WITH INVERTED V BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0756; DOTLESS BEH WITH V ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0758; HAH WITH INVERTED 3 DOTS BELOW; D; HAH */
+ JOINING_TYPE_R, /* 0759; DAL WITH VERTICAL 2 DOTS BELOW AND TAH ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 075A; DAL WITH INVERTED V BELOW; R; DAL */
+ JOINING_TYPE_R, /* 075B; REH WITH BAR; R; REH */
+ JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 075E; AIN WITH INVERTED 3 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 075F; AIN WITH VERTICAL 2 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 0760; DOTLESS FEH WITH 2 DOTS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 0761; DOTLESS FEH WITH INVERTED 3 DOTS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 0764; KEHEH WITH INVERTED 3 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */
+ JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */
+ JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */
+ JOINING_TYPE_D, /* 0768; NOON WITH TAH ABOVE; D; NOON */
+ JOINING_TYPE_D, /* 0769; NOON WITH V ABOVE; D; NOON */
+ JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */
+ JOINING_TYPE_R, /* 076B; REH WITH VERTICAL 2 DOTS ABOVE; R; REH */
+ JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */
+ JOINING_TYPE_D, /* 076D; SEEN WITH VERTICAL 2 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 076E; HAH WITH TAH BELOW; D; HAH */
+ JOINING_TYPE_D, /* 076F; HAH WITH TAH AND 2 DOTS BELOW; D; HAH */
+ JOINING_TYPE_D, /* 0770; SEEN WITH 2 DOTS AND TAH ABOVE; D; SEEN */
+ JOINING_TYPE_R, /* 0771; REH WITH 2 DOTS AND TAH ABOVE; R; REH */
+ JOINING_TYPE_D, /* 0772; HAH WITH TAH ABOVE; D; HAH */
+ JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */
+ JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */
+ JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 0777; DOTLESS YEH WITH DIGIT FOUR BELOW; D; YEH */
+ JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 077A; BURUSHASKI YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */
+ JOINING_TYPE_D, /* 077B; BURUSHASKI YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */
+ JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */
+ JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */
+
+ /* N'Ko Characters */
+
+ JOINING_TYPE_X, /* 0780 */
+ JOINING_TYPE_X, /* 0781 */
+ JOINING_TYPE_X, /* 0782 */
+ JOINING_TYPE_X, /* 0783 */
+ JOINING_TYPE_X, /* 0784 */
+ JOINING_TYPE_X, /* 0785 */
+ JOINING_TYPE_X, /* 0786 */
+ JOINING_TYPE_X, /* 0787 */
+ JOINING_TYPE_X, /* 0788 */
+ JOINING_TYPE_X, /* 0789 */
+ JOINING_TYPE_X, /* 078A */
+ JOINING_TYPE_X, /* 078B */
+ JOINING_TYPE_X, /* 078C */
+ JOINING_TYPE_X, /* 078D */
+ JOINING_TYPE_X, /* 078E */
+ JOINING_TYPE_X, /* 078F */
+ JOINING_TYPE_X, /* 0790 */
+ JOINING_TYPE_X, /* 0791 */
+ JOINING_TYPE_X, /* 0792 */
+ JOINING_TYPE_X, /* 0793 */
+ JOINING_TYPE_X, /* 0794 */
+ JOINING_TYPE_X, /* 0795 */
+ JOINING_TYPE_X, /* 0796 */
+ JOINING_TYPE_X, /* 0797 */
+ JOINING_TYPE_X, /* 0798 */
+ JOINING_TYPE_X, /* 0799 */
+ JOINING_TYPE_X, /* 079A */
+ JOINING_TYPE_X, /* 079B */
+ JOINING_TYPE_X, /* 079C */
+ JOINING_TYPE_X, /* 079D */
+ JOINING_TYPE_X, /* 079E */
+ JOINING_TYPE_X, /* 079F */
+ JOINING_TYPE_X, /* 07A0 */
+ JOINING_TYPE_X, /* 07A1 */
+ JOINING_TYPE_X, /* 07A2 */
+ JOINING_TYPE_X, /* 07A3 */
+ JOINING_TYPE_X, /* 07A4 */
+ JOINING_TYPE_X, /* 07A5 */
+ JOINING_TYPE_X, /* 07A6 */
+ JOINING_TYPE_X, /* 07A7 */
+ JOINING_TYPE_X, /* 07A8 */
+ JOINING_TYPE_X, /* 07A9 */
+ JOINING_TYPE_X, /* 07AA */
+ JOINING_TYPE_X, /* 07AB */
+ JOINING_TYPE_X, /* 07AC */
+ JOINING_TYPE_X, /* 07AD */
+ JOINING_TYPE_X, /* 07AE */
+ JOINING_TYPE_X, /* 07AF */
+ JOINING_TYPE_X, /* 07B0 */
+ JOINING_TYPE_X, /* 07B1 */
+ JOINING_TYPE_X, /* 07B2 */
+ JOINING_TYPE_X, /* 07B3 */
+ JOINING_TYPE_X, /* 07B4 */
+ JOINING_TYPE_X, /* 07B5 */
+ JOINING_TYPE_X, /* 07B6 */
+ JOINING_TYPE_X, /* 07B7 */
+ JOINING_TYPE_X, /* 07B8 */
+ JOINING_TYPE_X, /* 07B9 */
+ JOINING_TYPE_X, /* 07BA */
+ JOINING_TYPE_X, /* 07BB */
+ JOINING_TYPE_X, /* 07BC */
+ JOINING_TYPE_X, /* 07BD */
+ JOINING_TYPE_X, /* 07BE */
+ JOINING_TYPE_X, /* 07BF */
+ JOINING_TYPE_X, /* 07C0 */
+ JOINING_TYPE_X, /* 07C1 */
+ JOINING_TYPE_X, /* 07C2 */
+ JOINING_TYPE_X, /* 07C3 */
+ JOINING_TYPE_X, /* 07C4 */
+ JOINING_TYPE_X, /* 07C5 */
+ JOINING_TYPE_X, /* 07C6 */
+ JOINING_TYPE_X, /* 07C7 */
+ JOINING_TYPE_X, /* 07C8 */
+ JOINING_TYPE_X, /* 07C9 */
+ JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */
+ JOINING_TYPE_X, /* 07EB */
+ JOINING_TYPE_X, /* 07EC */
+ JOINING_TYPE_X, /* 07ED */
+ JOINING_TYPE_X, /* 07EE */
+ JOINING_TYPE_X, /* 07EF */
+ JOINING_TYPE_X, /* 07F0 */
+ JOINING_TYPE_X, /* 07F1 */
+ JOINING_TYPE_X, /* 07F2 */
+ JOINING_TYPE_X, /* 07F3 */
+ JOINING_TYPE_X, /* 07F4 */
+ JOINING_TYPE_X, /* 07F5 */
+ JOINING_TYPE_X, /* 07F6 */
+ JOINING_TYPE_X, /* 07F7 */
+ JOINING_TYPE_X, /* 07F8 */
+ JOINING_TYPE_X, /* 07F9 */
+ JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */
+
+ /* Mandaic Characters */
+
+ JOINING_TYPE_X, /* 07FB */
+ JOINING_TYPE_X, /* 07FC */
+ JOINING_TYPE_X, /* 07FD */
+ JOINING_TYPE_X, /* 07FE */
+ JOINING_TYPE_X, /* 07FF */
+ JOINING_TYPE_X, /* 0800 */
+ JOINING_TYPE_X, /* 0801 */
+ JOINING_TYPE_X, /* 0802 */
+ JOINING_TYPE_X, /* 0803 */
+ JOINING_TYPE_X, /* 0804 */
+ JOINING_TYPE_X, /* 0805 */
+ JOINING_TYPE_X, /* 0806 */
+ JOINING_TYPE_X, /* 0807 */
+ JOINING_TYPE_X, /* 0808 */
+ JOINING_TYPE_X, /* 0809 */
+ JOINING_TYPE_X, /* 080A */
+ JOINING_TYPE_X, /* 080B */
+ JOINING_TYPE_X, /* 080C */
+ JOINING_TYPE_X, /* 080D */
+ JOINING_TYPE_X, /* 080E */
+ JOINING_TYPE_X, /* 080F */
+ JOINING_TYPE_X, /* 0810 */
+ JOINING_TYPE_X, /* 0811 */
+ JOINING_TYPE_X, /* 0812 */
+ JOINING_TYPE_X, /* 0813 */
+ JOINING_TYPE_X, /* 0814 */
+ JOINING_TYPE_X, /* 0815 */
+ JOINING_TYPE_X, /* 0816 */
+ JOINING_TYPE_X, /* 0817 */
+ JOINING_TYPE_X, /* 0818 */
+ JOINING_TYPE_X, /* 0819 */
+ JOINING_TYPE_X, /* 081A */
+ JOINING_TYPE_X, /* 081B */
+ JOINING_TYPE_X, /* 081C */
+ JOINING_TYPE_X, /* 081D */
+ JOINING_TYPE_X, /* 081E */
+ JOINING_TYPE_X, /* 081F */
+ JOINING_TYPE_X, /* 0820 */
+ JOINING_TYPE_X, /* 0821 */
+ JOINING_TYPE_X, /* 0822 */
+ JOINING_TYPE_X, /* 0823 */
+ JOINING_TYPE_X, /* 0824 */
+ JOINING_TYPE_X, /* 0825 */
+ JOINING_TYPE_X, /* 0826 */
+ JOINING_TYPE_X, /* 0827 */
+ JOINING_TYPE_X, /* 0828 */
+ JOINING_TYPE_X, /* 0829 */
+ JOINING_TYPE_X, /* 082A */
+ JOINING_TYPE_X, /* 082B */
+ JOINING_TYPE_X, /* 082C */
+ JOINING_TYPE_X, /* 082D */
+ JOINING_TYPE_X, /* 082E */
+ JOINING_TYPE_X, /* 082F */
+ JOINING_TYPE_X, /* 0830 */
+ JOINING_TYPE_X, /* 0831 */
+ JOINING_TYPE_X, /* 0832 */
+ JOINING_TYPE_X, /* 0833 */
+ JOINING_TYPE_X, /* 0834 */
+ JOINING_TYPE_X, /* 0835 */
+ JOINING_TYPE_X, /* 0836 */
+ JOINING_TYPE_X, /* 0837 */
+ JOINING_TYPE_X, /* 0838 */
+ JOINING_TYPE_X, /* 0839 */
+ JOINING_TYPE_X, /* 083A */
+ JOINING_TYPE_X, /* 083B */
+ JOINING_TYPE_X, /* 083C */
+ JOINING_TYPE_X, /* 083D */
+ JOINING_TYPE_X, /* 083E */
+ JOINING_TYPE_X, /* 083F */
+ JOINING_TYPE_R, /* 0840; MANDAIC HALQA; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0841; MANDAIC AB; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0842; MANDAIC AG; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0843; MANDAIC AD; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0844; MANDAIC AH; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0845; MANDAIC USHENNA; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 0846; MANDAIC AZ; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0847; MANDAIC IT; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0848; MANDAIC ATT; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 0849; MANDAIC AKSA; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 084A; MANDAIC AK; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084B; MANDAIC AL; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084C; MANDAIC AM; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084D; MANDAIC AN; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084E; MANDAIC AS; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 084F; MANDAIC IN; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0850; MANDAIC AP; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0851; MANDAIC ASZ; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0852; MANDAIC AQ; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0853; MANDAIC AR; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 0854; MANDAIC ASH; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0855; MANDAIC AT; D; No_Joining_Group */
+ JOINING_TYPE_U, /* 0856; MANDAIC DUSHENNA; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0857; MANDAIC KAD; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0858; MANDAIC AIN; U; No_Joining_Group */
+
+ /* Arabic Extended-A Characters */
+
+ JOINING_TYPE_X, /* 0859 */
+ JOINING_TYPE_X, /* 085A */
+ JOINING_TYPE_X, /* 085B */
+ JOINING_TYPE_X, /* 085C */
+ JOINING_TYPE_X, /* 085D */
+ JOINING_TYPE_X, /* 085E */
+ JOINING_TYPE_X, /* 085F */
+ JOINING_TYPE_X, /* 0860 */
+ JOINING_TYPE_X, /* 0861 */
+ JOINING_TYPE_X, /* 0862 */
+ JOINING_TYPE_X, /* 0863 */
+ JOINING_TYPE_X, /* 0864 */
+ JOINING_TYPE_X, /* 0865 */
+ JOINING_TYPE_X, /* 0866 */
+ JOINING_TYPE_X, /* 0867 */
+ JOINING_TYPE_X, /* 0868 */
+ JOINING_TYPE_X, /* 0869 */
+ JOINING_TYPE_X, /* 086A */
+ JOINING_TYPE_X, /* 086B */
+ JOINING_TYPE_X, /* 086C */
+ JOINING_TYPE_X, /* 086D */
+ JOINING_TYPE_X, /* 086E */
+ JOINING_TYPE_X, /* 086F */
+ JOINING_TYPE_X, /* 0870 */
+ JOINING_TYPE_X, /* 0871 */
+ JOINING_TYPE_X, /* 0872 */
+ JOINING_TYPE_X, /* 0873 */
+ JOINING_TYPE_X, /* 0874 */
+ JOINING_TYPE_X, /* 0875 */
+ JOINING_TYPE_X, /* 0876 */
+ JOINING_TYPE_X, /* 0877 */
+ JOINING_TYPE_X, /* 0878 */
+ JOINING_TYPE_X, /* 0879 */
+ JOINING_TYPE_X, /* 087A */
+ JOINING_TYPE_X, /* 087B */
+ JOINING_TYPE_X, /* 087C */
+ JOINING_TYPE_X, /* 087D */
+ JOINING_TYPE_X, /* 087E */
+ JOINING_TYPE_X, /* 087F */
+ JOINING_TYPE_X, /* 0880 */
+ JOINING_TYPE_X, /* 0881 */
+ JOINING_TYPE_X, /* 0882 */
+ JOINING_TYPE_X, /* 0883 */
+ JOINING_TYPE_X, /* 0884 */
+ JOINING_TYPE_X, /* 0885 */
+ JOINING_TYPE_X, /* 0886 */
+ JOINING_TYPE_X, /* 0887 */
+ JOINING_TYPE_X, /* 0888 */
+ JOINING_TYPE_X, /* 0889 */
+ JOINING_TYPE_X, /* 088A */
+ JOINING_TYPE_X, /* 088B */
+ JOINING_TYPE_X, /* 088C */
+ JOINING_TYPE_X, /* 088D */
+ JOINING_TYPE_X, /* 088E */
+ JOINING_TYPE_X, /* 088F */
+ JOINING_TYPE_X, /* 0890 */
+ JOINING_TYPE_X, /* 0891 */
+ JOINING_TYPE_X, /* 0892 */
+ JOINING_TYPE_X, /* 0893 */
+ JOINING_TYPE_X, /* 0894 */
+ JOINING_TYPE_X, /* 0895 */
+ JOINING_TYPE_X, /* 0896 */
+ JOINING_TYPE_X, /* 0897 */
+ JOINING_TYPE_X, /* 0898 */
+ JOINING_TYPE_X, /* 0899 */
+ JOINING_TYPE_X, /* 089A */
+ JOINING_TYPE_X, /* 089B */
+ JOINING_TYPE_X, /* 089C */
+ JOINING_TYPE_X, /* 089D */
+ JOINING_TYPE_X, /* 089E */
+ JOINING_TYPE_X, /* 089F */
+ JOINING_TYPE_D, /* 08A0; DOTLESS BEH WITH V BELOW; D; BEH */
+ JOINING_TYPE_X, /* 08A1 */
+ JOINING_TYPE_D, /* 08A2; HAH WITH DOT BELOW AND 2 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 08A3; TAH WITH 2 DOTS ABOVE; D; TAH */
+ JOINING_TYPE_D, /* 08A4; DOTLESS FEH WITH DOT BELOW AND 3 DOTS ABOVE; D; FEH */
+ JOINING_TYPE_D, /* 08A5; QAF WITH DOT BELOW; D; QAF */
+ JOINING_TYPE_D, /* 08A6; LAM WITH DOUBLE BAR; D; LAM */
+ JOINING_TYPE_D, /* 08A7; MEEM WITH 3 DOTS ABOVE; D; MEEM */
+ JOINING_TYPE_D, /* 08A8; YEH WITH HAMZA ABOVE; D; YEH */
+ JOINING_TYPE_D, /* 08A9; YEH WITH DOT ABOVE; D; YEH */
+ JOINING_TYPE_R, /* 08AA; REH WITH LOOP; R; REH */
+ JOINING_TYPE_R, /* 08AB; WAW WITH DOT WITHIN; R; WAW */
+ JOINING_TYPE_R, /* 08AC; ROHINGYA YEH; R; ROHINGYA YEH */
+
+};
+
+#define JOINING_TABLE_FIRST 0x0600
+#define JOINING_TABLE_LAST 0x08AC
+
+
+static const uint16_t shaping_table[][4] =
+{
+ {0x0000, 0x0000, 0x0000, 0xFE80}, /* U+0621 ARABIC LETTER HAMZA ISOLATED FORM */
+ {0x0000, 0x0000, 0xFE82, 0xFE81}, /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
+ {0x0000, 0x0000, 0xFE84, 0xFE83}, /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ {0x0000, 0x0000, 0xFE86, 0xFE85}, /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
+ {0x0000, 0x0000, 0xFE88, 0xFE87}, /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
+ {0xFE8B, 0xFE8C, 0xFE8A, 0xFE89}, /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
+ {0x0000, 0x0000, 0xFE8E, 0xFE8D}, /* U+0627 ARABIC LETTER ALEF */
+ {0xFE91, 0xFE92, 0xFE90, 0xFE8F}, /* U+0628 ARABIC LETTER BEH */
+ {0x0000, 0x0000, 0xFE94, 0xFE93}, /* U+0629 ARABIC LETTER TEH MARBUTA */
+ {0xFE97, 0xFE98, 0xFE96, 0xFE95}, /* U+062A ARABIC LETTER TEH */
+ {0xFE9B, 0xFE9C, 0xFE9A, 0xFE99}, /* U+062B ARABIC LETTER THEH */
+ {0xFE9F, 0xFEA0, 0xFE9E, 0xFE9D}, /* U+062C ARABIC LETTER JEEM */
+ {0xFEA3, 0xFEA4, 0xFEA2, 0xFEA1}, /* U+062D ARABIC LETTER HAH */
+ {0xFEA7, 0xFEA8, 0xFEA6, 0xFEA5}, /* U+062E ARABIC LETTER KHAH */
+ {0x0000, 0x0000, 0xFEAA, 0xFEA9}, /* U+062F ARABIC LETTER DAL */
+ {0x0000, 0x0000, 0xFEAC, 0xFEAB}, /* U+0630 ARABIC LETTER THAL */
+ {0x0000, 0x0000, 0xFEAE, 0xFEAD}, /* U+0631 ARABIC LETTER REH */
+ {0x0000, 0x0000, 0xFEB0, 0xFEAF}, /* U+0632 ARABIC LETTER ZAIN */
+ {0xFEB3, 0xFEB4, 0xFEB2, 0xFEB1}, /* U+0633 ARABIC LETTER SEEN */
+ {0xFEB7, 0xFEB8, 0xFEB6, 0xFEB5}, /* U+0634 ARABIC LETTER SHEEN */
+ {0xFEBB, 0xFEBC, 0xFEBA, 0xFEB9}, /* U+0635 ARABIC LETTER SAD */
+ {0xFEBF, 0xFEC0, 0xFEBE, 0xFEBD}, /* U+0636 ARABIC LETTER DAD */
+ {0xFEC3, 0xFEC4, 0xFEC2, 0xFEC1}, /* U+0637 ARABIC LETTER TAH */
+ {0xFEC7, 0xFEC8, 0xFEC6, 0xFEC5}, /* U+0638 ARABIC LETTER ZAH */
+ {0xFECB, 0xFECC, 0xFECA, 0xFEC9}, /* U+0639 ARABIC LETTER AIN */
+ {0xFECF, 0xFED0, 0xFECE, 0xFECD}, /* U+063A ARABIC LETTER GHAIN */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063B */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063C */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063D */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063E */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+063F */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0640 */
+ {0xFED3, 0xFED4, 0xFED2, 0xFED1}, /* U+0641 ARABIC LETTER FEH */
+ {0xFED7, 0xFED8, 0xFED6, 0xFED5}, /* U+0642 ARABIC LETTER QAF */
+ {0xFEDB, 0xFEDC, 0xFEDA, 0xFED9}, /* U+0643 ARABIC LETTER KAF */
+ {0xFEDF, 0xFEE0, 0xFEDE, 0xFEDD}, /* U+0644 ARABIC LETTER LAM */
+ {0xFEE3, 0xFEE4, 0xFEE2, 0xFEE1}, /* U+0645 ARABIC LETTER MEEM */
+ {0xFEE7, 0xFEE8, 0xFEE6, 0xFEE5}, /* U+0646 ARABIC LETTER NOON */
+ {0xFEEB, 0xFEEC, 0xFEEA, 0xFEE9}, /* U+0647 ARABIC LETTER HEH */
+ {0x0000, 0x0000, 0xFEEE, 0xFEED}, /* U+0648 ARABIC LETTER WAW */
+ {0xFBE8, 0xFBE9, 0xFEF0, 0xFEEF}, /* U+0649 ARABIC LETTER */
+ {0xFEF3, 0xFEF4, 0xFEF2, 0xFEF1}, /* U+064A ARABIC LETTER YEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064B */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064C */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064D */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064E */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+064F */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0650 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0651 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0652 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0653 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0654 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0655 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0656 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0657 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0658 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0659 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065A */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065B */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065C */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065D */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065E */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+065F */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0660 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0661 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0662 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0663 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0664 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0665 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0666 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0667 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0668 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0669 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066A */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066B */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066C */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066D */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066E */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+066F */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0670 */
+ {0x0000, 0x0000, 0xFB51, 0xFB50}, /* U+0671 ARABIC LETTER ALEF WASLA */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0672 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0673 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0674 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0675 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0676 */
+ {0x0000, 0x0000, 0x0000, 0xFBDD}, /* U+0677 ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0678 */
+ {0xFB68, 0xFB69, 0xFB67, 0xFB66}, /* U+0679 ARABIC LETTER TTEH */
+ {0xFB60, 0xFB61, 0xFB5F, 0xFB5E}, /* U+067A ARABIC LETTER TTEHEH */
+ {0xFB54, 0xFB55, 0xFB53, 0xFB52}, /* U+067B ARABIC LETTER BEEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+067C */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+067D */
+ {0xFB58, 0xFB59, 0xFB57, 0xFB56}, /* U+067E ARABIC LETTER PEH */
+ {0xFB64, 0xFB65, 0xFB63, 0xFB62}, /* U+067F ARABIC LETTER TEHEH */
+ {0xFB5C, 0xFB5D, 0xFB5B, 0xFB5A}, /* U+0680 ARABIC LETTER BEHEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0681 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0682 */
+ {0xFB78, 0xFB79, 0xFB77, 0xFB76}, /* U+0683 ARABIC LETTER NYEH */
+ {0xFB74, 0xFB75, 0xFB73, 0xFB72}, /* U+0684 ARABIC LETTER DYEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0685 */
+ {0xFB7C, 0xFB7D, 0xFB7B, 0xFB7A}, /* U+0686 ARABIC LETTER TCHEH */
+ {0xFB80, 0xFB81, 0xFB7F, 0xFB7E}, /* U+0687 ARABIC LETTER TCHEHEH */
+ {0x0000, 0x0000, 0xFB89, 0xFB88}, /* U+0688 ARABIC LETTER DDAL */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0689 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+068A */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+068B */
+ {0x0000, 0x0000, 0xFB85, 0xFB84}, /* U+068C ARABIC LETTER DAHAL */
+ {0x0000, 0x0000, 0xFB83, 0xFB82}, /* U+068D ARABIC LETTER DDAHAL */
+ {0x0000, 0x0000, 0xFB87, 0xFB86}, /* U+068E ARABIC LETTER DUL */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+068F */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0690 */
+ {0x0000, 0x0000, 0xFB8D, 0xFB8C}, /* U+0691 ARABIC LETTER RREH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0692 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0693 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0694 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0695 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0696 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0697 */
+ {0x0000, 0x0000, 0xFB8B, 0xFB8A}, /* U+0698 ARABIC LETTER JEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+0699 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069A */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069B */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069C */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069D */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069E */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+069F */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A0 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A1 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A2 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A3 */
+ {0xFB6C, 0xFB6D, 0xFB6B, 0xFB6A}, /* U+06A4 ARABIC LETTER VEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A5 */
+ {0xFB70, 0xFB71, 0xFB6F, 0xFB6E}, /* U+06A6 ARABIC LETTER PEHEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A7 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A8 */
+ {0xFB90, 0xFB91, 0xFB8F, 0xFB8E}, /* U+06A9 ARABIC LETTER KEHEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AA */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AB */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AC */
+ {0xFBD5, 0xFBD6, 0xFBD4, 0xFBD3}, /* U+06AD ARABIC LETTER NG */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AE */
+ {0xFB94, 0xFB95, 0xFB93, 0xFB92}, /* U+06AF ARABIC LETTER GAF */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B0 */
+ {0xFB9C, 0xFB9D, 0xFB9B, 0xFB9A}, /* U+06B1 ARABIC LETTER NGOEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B2 */
+ {0xFB98, 0xFB99, 0xFB97, 0xFB96}, /* U+06B3 ARABIC LETTER GUEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B4 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B5 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B6 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B7 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B8 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B9 */
+ {0x0000, 0x0000, 0xFB9F, 0xFB9E}, /* U+06BA ARABIC LETTER NOON GHUNNA */
+ {0xFBA2, 0xFBA3, 0xFBA1, 0xFBA0}, /* U+06BB ARABIC LETTER RNOON */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BC */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BD */
+ {0xFBAC, 0xFBAD, 0xFBAB, 0xFBAA}, /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BF */
+ {0x0000, 0x0000, 0xFBA5, 0xFBA4}, /* U+06C0 ARABIC LETTER HEH WITH YEH ABOVE */
+ {0xFBA8, 0xFBA9, 0xFBA7, 0xFBA6}, /* U+06C1 ARABIC LETTER HEH GOAL */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C2 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C3 */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C4 */
+ {0x0000, 0x0000, 0xFBE1, 0xFBE0}, /* U+06C5 ARABIC LETTER KIRGHIZ OE */
+ {0x0000, 0x0000, 0xFBDA, 0xFBD9}, /* U+06C6 ARABIC LETTER OE */
+ {0x0000, 0x0000, 0xFBD8, 0xFBD7}, /* U+06C7 ARABIC LETTER U */
+ {0x0000, 0x0000, 0xFBDC, 0xFBDB}, /* U+06C8 ARABIC LETTER YU */
+ {0x0000, 0x0000, 0xFBE3, 0xFBE2}, /* U+06C9 ARABIC LETTER KIRGHIZ YU */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CA */
+ {0x0000, 0x0000, 0xFBDF, 0xFBDE}, /* U+06CB ARABIC LETTER VE */
+ {0xFBFE, 0xFBFF, 0xFBFD, 0xFBFC}, /* U+06CC ARABIC LETTER FARSI YEH */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CD */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CE */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CF */
+ {0xFBE6, 0xFBE7, 0xFBE5, 0xFBE4}, /* U+06D0 ARABIC LETTER E */
+ {0x0000, 0x0000, 0x0000, 0x0000}, /* U+06D1 */
+ {0x0000, 0x0000, 0xFBAF, 0xFBAE}, /* U+06D2 ARABIC LETTER YEH BARREE */
+ {0x0000, 0x0000, 0xFBB1, 0xFBB0}, /* U+06D3 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE */
+};
+
+#define SHAPING_TABLE_FIRST 0x0621
+#define SHAPING_TABLE_LAST 0x06D3
+
+
+static const struct ligature_set_t {
+ uint16_t first;
+ struct ligature_pairs_t {
+ uint16_t second;
+ uint16_t ligature;
+ } ligatures[4];
+} ligature_table[] =
+{
+ { 0xFEDF, {
+ { 0xFE88, 0xFEF9 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
+ { 0xFE82, 0xFEF5 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
+ { 0xFE8E, 0xFEFB }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+ { 0xFE84, 0xFEF7 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
+ }},
+ { 0xFEE0, {
+ { 0xFE88, 0xFEFA }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
+ { 0xFE82, 0xFEF6 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
+ { 0xFE8E, 0xFEFC }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+ { 0xFE84, 0xFEF8 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
+ }},
+};
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */
+
+/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
new file mode 100644
index 0000000000..a57e81a5ec
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -0,0 +1,356 @@
+/*
+ * Copyright © 2010,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh"
+
+
+/* buffer var allocations */
+#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
+
+
+/*
+ * Bits used in the joining tables
+ */
+enum {
+ JOINING_TYPE_U = 0,
+ JOINING_TYPE_L = 1,
+ JOINING_TYPE_R = 2,
+ JOINING_TYPE_D = 3,
+ JOINING_TYPE_C = JOINING_TYPE_D,
+ JOINING_GROUP_ALAPH = 4,
+ JOINING_GROUP_DALATH_RISH = 5,
+ NUM_STATE_MACHINE_COLS = 6,
+
+ JOINING_TYPE_T = 7,
+ JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */
+};
+
+/*
+ * Joining types:
+ */
+
+#include "hb-ot-shape-complex-arabic-table.hh"
+
+static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
+{
+ if (likely (hb_in_range<hb_codepoint_t> (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) {
+ unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST];
+ if (likely (j_type != JOINING_TYPE_X))
+ return j_type;
+ }
+
+ /* Mongolian joining data is not in ArabicJoining.txt yet. */
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1800, 0x18AF)))
+ {
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1880, 0x1886)))
+ return JOINING_TYPE_U;
+
+ /* All letters, SIBE SYLLABLE BOUNDARY MARKER, and NIRUGU are D */
+ if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) |
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER)))
+ || u == 0x1807 || u == 0x180A)
+ return JOINING_TYPE_D;
+ }
+
+ /* 'Phags-pa joining data is not in ArabicJoining.txt yet. */
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872)))
+ {
+ if (unlikely (u == 0xA872))
+ return JOINING_TYPE_L;
+
+ return JOINING_TYPE_D;
+ }
+
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D)))
+ {
+ return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
+ }
+
+ return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))) ?
+ JOINING_TYPE_T : JOINING_TYPE_U;
+}
+
+static const hb_tag_t arabic_features[] =
+{
+ HB_TAG('i','n','i','t'),
+ HB_TAG('m','e','d','i'),
+ HB_TAG('f','i','n','a'),
+ HB_TAG('i','s','o','l'),
+ /* Syriac */
+ HB_TAG('m','e','d','2'),
+ HB_TAG('f','i','n','2'),
+ HB_TAG('f','i','n','3'),
+ HB_TAG_NONE
+};
+
+
+/* Same order as the feature array */
+enum {
+ INIT,
+ MEDI,
+ FINA,
+ ISOL,
+
+ /* Syriac */
+ MED2,
+ FIN2,
+ FIN3,
+
+ NONE,
+
+ ARABIC_NUM_FEATURES = NONE
+};
+
+static const struct arabic_state_table_entry {
+ uint8_t prev_action;
+ uint8_t curr_action;
+ uint16_t next_state;
+} arabic_state_table[][NUM_STATE_MACHINE_COLS] =
+{
+ /* jt_U, jt_L, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */
+
+ /* State 0: prev was U, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
+
+ /* State 1: prev was R or ISOL/ALAPH, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
+
+ /* State 2: prev was D/L in ISOL form, willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
+
+ /* State 3: prev was D in FINA form, willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
+
+ /* State 4: prev was FINA ALAPH, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
+
+ /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
+
+ /* State 6: prev was DALATH/RISH, not willing to join. */
+ { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
+};
+
+
+static void
+arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
+collect_features_arabic (hb_ot_shape_planner_t *plan)
+{
+ hb_ot_map_builder_t *map = &plan->map;
+
+ /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
+ * then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH
+ * ligature work correctly. It's unfortunate though...
+ *
+ * This also makes Arial Bold in Windows7 work. See:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=644184
+ *
+ * TODO: Add test cases for these two.
+ */
+
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+
+ map->add_gsub_pause (NULL);
+
+ for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
+ map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /* The first four features have fallback. */
+
+ map->add_gsub_pause (NULL);
+
+ map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
+ map->add_gsub_pause (arabic_fallback_shape);
+
+ map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+ map->add_gsub_pause (NULL);
+
+ map->add_global_bool_feature (HB_TAG('c','s','w','h'));
+ map->add_global_bool_feature (HB_TAG('m','s','e','t'));
+}
+
+#include "hb-ot-shape-complex-arabic-fallback.hh"
+
+struct arabic_shape_plan_t
+{
+ ASSERT_POD ();
+
+ /* The "+ 1" in the next array is to accommodate for the "NONE" command,
+ * which is not an OpenType feature, but this simplifies the code by not
+ * having to do a "if (... < NONE) ..." and just rely on the fact that
+ * mask_array[NONE] == 0. */
+ hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
+
+ bool do_fallback;
+ arabic_fallback_plan_t *fallback_plan;
+};
+
+static void *
+data_create_arabic (const hb_ot_shape_plan_t *plan)
+{
+ arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t));
+ if (unlikely (!arabic_plan))
+ return NULL;
+
+ arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
+ for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
+ arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
+ if (i < 4)
+ arabic_plan->do_fallback = arabic_plan->do_fallback && plan->map.needs_fallback (arabic_features[i]);
+ }
+
+ return arabic_plan;
+}
+
+static void
+data_destroy_arabic (void *data)
+{
+ arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data;
+
+ arabic_fallback_plan_destroy (arabic_plan->fallback_plan);
+
+ free (data);
+}
+
+static void
+arabic_joining (hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ unsigned int prev = (unsigned int) -1, state = 0;
+
+ HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
+
+ /* Check pre-context */
+ if (!(buffer->flags & HB_BUFFER_FLAG_BOT))
+ for (unsigned int i = 0; i < buffer->context_len[0]; i++)
+ {
+ unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
+
+ if (unlikely (this_type == JOINING_TYPE_T))
+ continue;
+
+ const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+ state = entry->next_state;
+ break;
+ }
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ unsigned int this_type = get_joining_type (buffer->info[i].codepoint, _hb_glyph_info_get_general_category (&buffer->info[i]));
+
+ if (unlikely (this_type == JOINING_TYPE_T)) {
+ buffer->info[i].arabic_shaping_action() = NONE;
+ continue;
+ }
+
+ const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+
+ if (entry->prev_action != NONE && prev != (unsigned int) -1)
+ buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+
+ buffer->info[i].arabic_shaping_action() = entry->curr_action;
+
+ prev = i;
+ state = entry->next_state;
+ }
+
+ if (!(buffer->flags & HB_BUFFER_FLAG_EOT))
+ for (unsigned int i = 0; i < buffer->context_len[1]; i++)
+ {
+ unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i]));
+
+ if (unlikely (this_type == JOINING_TYPE_T))
+ continue;
+
+ const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+ if (entry->prev_action != NONE && prev != (unsigned int) -1)
+ buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+ break;
+ }
+
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
+}
+
+static void
+setup_masks_arabic (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
+{
+ const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
+
+ arabic_joining (buffer);
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()];
+}
+
+
+static void
+arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
+
+ if (!arabic_plan->do_fallback)
+ return;
+
+retry:
+ arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_atomic_ptr_get (&arabic_plan->fallback_plan);
+ if (unlikely (!fallback_plan))
+ {
+ /* This sucks. We need a font to build the fallback plan... */
+ fallback_plan = arabic_fallback_plan_create (plan, font);
+ if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, NULL, fallback_plan))) {
+ arabic_fallback_plan_destroy (fallback_plan);
+ goto retry;
+ }
+ }
+
+ arabic_fallback_plan_shape (fallback_plan, font, buffer);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
+{
+ "arabic",
+ collect_features_arabic,
+ NULL, /* override_features */
+ data_create_arabic,
+ data_destroy_arabic,
+ NULL, /* preprocess_text_arabic */
+ NULL, /* normalization_preference */
+ NULL, /* decompose */
+ NULL, /* compose */
+ setup_masks_arabic,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
+ true, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
new file mode 100644
index 0000000000..d6afa0e1c1
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
@@ -0,0 +1,220 @@
+/*
+ * Copyright © 2010,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+/* TODO Add kana, and other small shapers here */
+
+
+/* The default shaper *only* adds additional per-script features.*/
+
+static const hb_tag_t hangul_features[] =
+{
+ HB_TAG('l','j','m','o'),
+ HB_TAG('v','j','m','o'),
+ HB_TAG('t','j','m','o'),
+ HB_TAG_NONE
+};
+
+static const hb_tag_t tibetan_features[] =
+{
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
+ HB_TAG_NONE
+};
+
+static void
+collect_features_default (hb_ot_shape_planner_t *plan)
+{
+ const hb_tag_t *script_features = NULL;
+
+ switch ((hb_tag_t) plan->props.script)
+ {
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_HANGUL:
+ script_features = hangul_features;
+ break;
+
+ /* Unicode-2.0 additions */
+ case HB_SCRIPT_TIBETAN:
+ script_features = tibetan_features;
+ break;
+ }
+
+ for (; script_features && *script_features; script_features++)
+ plan->map.add_global_bool_feature (*script_features);
+}
+
+static hb_ot_shape_normalization_mode_t
+normalization_preference_default (const hb_segment_properties_t *props)
+{
+ return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
+}
+
+static bool
+compose_default (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
+{
+ /* Hebrew presentation-form shaping.
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=728866
+ * Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
+ * Note that some letters do not have a dagesh presForm encoded.
+ */
+ static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
+ 0xFB30, /* ALEF */
+ 0xFB31, /* BET */
+ 0xFB32, /* GIMEL */
+ 0xFB33, /* DALET */
+ 0xFB34, /* HE */
+ 0xFB35, /* VAV */
+ 0xFB36, /* ZAYIN */
+ 0x0000, /* HET */
+ 0xFB38, /* TET */
+ 0xFB39, /* YOD */
+ 0xFB3A, /* FINAL KAF */
+ 0xFB3B, /* KAF */
+ 0xFB3C, /* LAMED */
+ 0x0000, /* FINAL MEM */
+ 0xFB3E, /* MEM */
+ 0x0000, /* FINAL NUN */
+ 0xFB40, /* NUN */
+ 0xFB41, /* SAMEKH */
+ 0x0000, /* AYIN */
+ 0xFB43, /* FINAL PE */
+ 0xFB44, /* PE */
+ 0x0000, /* FINAL TSADI */
+ 0xFB46, /* TSADI */
+ 0xFB47, /* QOF */
+ 0xFB48, /* RESH */
+ 0xFB49, /* SHIN */
+ 0xFB4A /* TAV */
+ };
+
+ bool found = c->unicode->compose (a, b, ab);
+
+ if (!found && (b & ~0x7F) == 0x0580) {
+ /* Special-case Hebrew presentation forms that are excluded from
+ * standard normalization, but wanted for old fonts. */
+ switch (b) {
+ case 0x05B4: /* HIRIQ */
+ if (a == 0x05D9) { /* YOD */
+ *ab = 0xFB1D;
+ found = true;
+ }
+ break;
+ case 0x05B7: /* patah */
+ if (a == 0x05F2) { /* YIDDISH YOD YOD */
+ *ab = 0xFB1F;
+ found = true;
+ } else if (a == 0x05D0) { /* ALEF */
+ *ab = 0xFB2E;
+ found = true;
+ }
+ break;
+ case 0x05B8: /* QAMATS */
+ if (a == 0x05D0) { /* ALEF */
+ *ab = 0xFB2F;
+ found = true;
+ }
+ break;
+ case 0x05B9: /* HOLAM */
+ if (a == 0x05D5) { /* VAV */
+ *ab = 0xFB4B;
+ found = true;
+ }
+ break;
+ case 0x05BC: /* DAGESH */
+ if (a >= 0x05D0 && a <= 0x05EA) {
+ *ab = sDageshForms[a - 0x05D0];
+ found = (*ab != 0);
+ } else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
+ *ab = 0xFB2C;
+ found = true;
+ } else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
+ *ab = 0xFB2D;
+ found = true;
+ }
+ break;
+ case 0x05BF: /* RAFE */
+ switch (a) {
+ case 0x05D1: /* BET */
+ *ab = 0xFB4C;
+ found = true;
+ break;
+ case 0x05DB: /* KAF */
+ *ab = 0xFB4D;
+ found = true;
+ break;
+ case 0x05E4: /* PE */
+ *ab = 0xFB4E;
+ found = true;
+ break;
+ }
+ break;
+ case 0x05C1: /* SHIN DOT */
+ if (a == 0x05E9) { /* SHIN */
+ *ab = 0xFB2A;
+ found = true;
+ } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
+ *ab = 0xFB2C;
+ found = true;
+ }
+ break;
+ case 0x05C2: /* SIN DOT */
+ if (a == 0x05E9) { /* SHIN */
+ *ab = 0xFB2B;
+ found = true;
+ } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
+ *ab = 0xFB2D;
+ found = true;
+ }
+ break;
+ }
+ }
+
+ return found;
+}
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
+{
+ "default",
+ collect_features_default,
+ NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ NULL, /* preprocess_text */
+ normalization_preference_default,
+ NULL, /* decompose */
+ compose_default,
+ NULL, /* setup_masks */
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+ true, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
new file mode 100644
index 0000000000..612f7b788a
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
@@ -0,0 +1,1443 @@
+
+#line 1 "hb-ot-shape-complex-indic-machine.rl"
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-ot-shape-complex-indic-machine.hh"
+static const unsigned char _indic_syllable_machine_trans_keys[] = {
+ 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u,
+ 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 4u, 4u, 6u, 6u,
+ 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u,
+ 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u,
+ 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u,
+ 5u, 7u, 7u, 7u, 4u, 4u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u,
+ 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u,
+ 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 4u, 4u, 6u, 6u,
+ 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u,
+ 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u, 7u, 7u,
+ 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u,
+ 7u, 7u, 4u, 4u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u,
+ 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 5u, 7u, 5u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u,
+ 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 1u, 16u, 13u, 13u, 4u, 4u, 6u, 6u,
+ 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u,
+ 6u, 6u, 16u, 16u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u,
+ 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u,
+ 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
+ 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, 3u, 14u, 4u, 14u, 1u, 16u,
+ 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u,
+ 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 3u, 14u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u,
+ 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
+ 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u,
+ 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u,
+ 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 1u, 16u, 3u, 14u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u,
+ 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u,
+ 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u,
+ 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u,
+ 3u, 14u, 4u, 14u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u,
+ 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u,
+ 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u,
+ 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 3u, 14u, 1u, 16u, 3u, 17u, 1u, 16u, 4u, 14u, 1u, 16u,
+ 3u, 17u, 3u, 14u, 4u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 14u, 3u, 14u,
+ 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
+ 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 8u, 14u, 3u, 17u, 3u, 9u, 8u, 9u,
+ 3u, 9u, 3u, 13u, 1u, 16u, 0
+};
+
+static const char _indic_syllable_machine_key_spans[] = {
+ 16, 1, 3, 3, 1, 3, 3, 1,
+ 3, 3, 1, 3, 3, 1, 1, 1,
+ 1, 4, 1, 1, 4, 1, 1, 4,
+ 1, 1, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 16, 1, 3, 3,
+ 1, 3, 3, 1, 3, 3, 1, 3,
+ 3, 1, 1, 1, 1, 4, 1, 1,
+ 4, 1, 1, 4, 1, 1, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 16, 1, 3, 3, 1, 3, 3, 1,
+ 3, 3, 1, 3, 3, 1, 1, 1,
+ 1, 4, 1, 1, 4, 1, 1, 4,
+ 1, 1, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 16, 1, 3, 3, 1,
+ 3, 3, 1, 3, 3, 1, 3, 3,
+ 1, 1, 1, 1, 4, 1, 1, 4,
+ 1, 1, 4, 1, 1, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 3, 3, 3, 3, 1, 3, 3,
+ 1, 3, 3, 1, 16, 1, 1, 1,
+ 1, 4, 1, 1, 4, 1, 1, 4,
+ 1, 1, 16, 15, 12, 11, 16, 15,
+ 12, 11, 16, 15, 12, 11, 16, 15,
+ 12, 11, 16, 15, 12, 11, 10, 7,
+ 5, 1, 1, 15, 7, 2, 7, 11,
+ 12, 12, 11, 10, 12, 11, 10, 12,
+ 11, 10, 12, 11, 9, 12, 11, 16,
+ 12, 12, 16, 16, 16, 16, 16, 12,
+ 12, 16, 16, 16, 16, 16, 12, 12,
+ 16, 16, 16, 16, 16, 12, 12, 16,
+ 16, 16, 16, 16, 12, 12, 12, 12,
+ 11, 16, 15, 12, 11, 16, 15, 12,
+ 11, 16, 15, 12, 11, 16, 15, 12,
+ 11, 10, 7, 5, 1, 1, 15, 7,
+ 2, 7, 11, 12, 12, 11, 10, 12,
+ 11, 10, 12, 11, 10, 12, 11, 9,
+ 12, 16, 12, 12, 16, 16, 16, 16,
+ 16, 12, 12, 16, 16, 16, 16, 16,
+ 12, 12, 16, 16, 16, 16, 16, 12,
+ 12, 16, 16, 16, 16, 11, 16, 12,
+ 12, 11, 16, 15, 12, 11, 16, 15,
+ 12, 11, 16, 15, 12, 11, 16, 15,
+ 12, 11, 10, 7, 5, 1, 1, 15,
+ 7, 2, 7, 11, 12, 12, 11, 10,
+ 12, 11, 10, 12, 11, 10, 12, 11,
+ 9, 12, 16, 12, 12, 16, 16, 16,
+ 16, 16, 12, 12, 16, 16, 16, 16,
+ 16, 12, 12, 16, 16, 16, 16, 16,
+ 12, 12, 16, 16, 16, 16, 16, 11,
+ 12, 11, 12, 12, 11, 16, 15, 12,
+ 11, 16, 15, 12, 11, 16, 15, 12,
+ 11, 16, 15, 12, 11, 10, 7, 5,
+ 1, 1, 15, 7, 2, 7, 11, 12,
+ 12, 11, 10, 12, 11, 10, 12, 11,
+ 10, 12, 11, 9, 12, 16, 12, 12,
+ 16, 16, 16, 16, 16, 12, 12, 16,
+ 16, 16, 16, 16, 12, 12, 16, 16,
+ 16, 16, 16, 12, 12, 16, 16, 16,
+ 16, 16, 12, 16, 15, 16, 11, 16,
+ 15, 12, 11, 5, 1, 1, 12, 12,
+ 16, 12, 11, 10, 12, 11, 10, 12,
+ 11, 10, 12, 11, 7, 15, 7, 2,
+ 7, 11, 16
+};
+
+static const short _indic_syllable_machine_index_offsets[] = {
+ 0, 17, 19, 23, 27, 29, 33, 37,
+ 39, 43, 47, 49, 53, 57, 59, 61,
+ 63, 65, 70, 72, 74, 79, 81, 83,
+ 88, 90, 92, 104, 116, 128, 140, 152,
+ 164, 176, 188, 200, 212, 229, 231, 235,
+ 239, 241, 245, 249, 251, 255, 259, 261,
+ 265, 269, 271, 273, 275, 277, 282, 284,
+ 286, 291, 293, 295, 300, 302, 304, 316,
+ 328, 340, 352, 364, 376, 388, 400, 412,
+ 424, 441, 443, 447, 451, 453, 457, 461,
+ 463, 467, 471, 473, 477, 481, 483, 485,
+ 487, 489, 494, 496, 498, 503, 505, 507,
+ 512, 514, 516, 528, 540, 552, 564, 576,
+ 588, 600, 612, 624, 641, 643, 647, 651,
+ 653, 657, 661, 663, 667, 671, 673, 677,
+ 681, 683, 685, 687, 689, 694, 696, 698,
+ 703, 705, 707, 712, 714, 716, 728, 740,
+ 752, 764, 776, 788, 800, 812, 824, 836,
+ 848, 860, 864, 868, 872, 876, 878, 882,
+ 886, 888, 892, 896, 898, 915, 917, 919,
+ 921, 923, 928, 930, 932, 937, 939, 941,
+ 946, 948, 950, 967, 983, 996, 1008, 1025,
+ 1041, 1054, 1066, 1083, 1099, 1112, 1124, 1141,
+ 1157, 1170, 1182, 1199, 1215, 1228, 1240, 1251,
+ 1259, 1265, 1267, 1269, 1285, 1293, 1296, 1304,
+ 1316, 1329, 1342, 1354, 1365, 1378, 1390, 1401,
+ 1414, 1426, 1437, 1450, 1462, 1472, 1485, 1497,
+ 1514, 1527, 1540, 1557, 1574, 1591, 1608, 1625,
+ 1638, 1651, 1668, 1685, 1702, 1719, 1736, 1749,
+ 1762, 1779, 1796, 1813, 1830, 1847, 1860, 1873,
+ 1890, 1907, 1924, 1941, 1958, 1971, 1984, 1997,
+ 2010, 2022, 2039, 2055, 2068, 2080, 2097, 2113,
+ 2126, 2138, 2155, 2171, 2184, 2196, 2213, 2229,
+ 2242, 2254, 2265, 2273, 2279, 2281, 2283, 2299,
+ 2307, 2310, 2318, 2330, 2343, 2356, 2368, 2379,
+ 2392, 2404, 2415, 2428, 2440, 2451, 2464, 2476,
+ 2486, 2499, 2516, 2529, 2542, 2559, 2576, 2593,
+ 2610, 2627, 2640, 2653, 2670, 2687, 2704, 2721,
+ 2738, 2751, 2764, 2781, 2798, 2815, 2832, 2849,
+ 2862, 2875, 2892, 2909, 2926, 2943, 2955, 2972,
+ 2985, 2998, 3010, 3027, 3043, 3056, 3068, 3085,
+ 3101, 3114, 3126, 3143, 3159, 3172, 3184, 3201,
+ 3217, 3230, 3242, 3253, 3261, 3267, 3269, 3271,
+ 3287, 3295, 3298, 3306, 3318, 3331, 3344, 3356,
+ 3367, 3380, 3392, 3403, 3416, 3428, 3439, 3452,
+ 3464, 3474, 3487, 3504, 3517, 3530, 3547, 3564,
+ 3581, 3598, 3615, 3628, 3641, 3658, 3675, 3692,
+ 3709, 3726, 3739, 3752, 3769, 3786, 3803, 3820,
+ 3837, 3850, 3863, 3880, 3897, 3914, 3931, 3948,
+ 3960, 3973, 3985, 3998, 4011, 4023, 4040, 4056,
+ 4069, 4081, 4098, 4114, 4127, 4139, 4156, 4172,
+ 4185, 4197, 4214, 4230, 4243, 4255, 4266, 4274,
+ 4280, 4282, 4284, 4300, 4308, 4311, 4319, 4331,
+ 4344, 4357, 4369, 4380, 4393, 4405, 4416, 4429,
+ 4441, 4452, 4465, 4477, 4487, 4500, 4517, 4530,
+ 4543, 4560, 4577, 4594, 4611, 4628, 4641, 4654,
+ 4671, 4688, 4705, 4722, 4739, 4752, 4765, 4782,
+ 4799, 4816, 4833, 4850, 4863, 4876, 4893, 4910,
+ 4927, 4944, 4961, 4974, 4991, 5007, 5024, 5036,
+ 5053, 5069, 5082, 5094, 5100, 5102, 5104, 5117,
+ 5130, 5147, 5160, 5172, 5183, 5196, 5208, 5219,
+ 5232, 5244, 5255, 5268, 5280, 5288, 5304, 5312,
+ 5315, 5323, 5335
+};
+
+static const short _indic_syllable_machine_indicies[] = {
+ 1, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 3, 0, 4, 4, 5, 0, 6,
+ 6, 5, 0, 5, 0, 7, 7, 8,
+ 0, 9, 9, 8, 0, 8, 0, 10,
+ 10, 11, 0, 12, 12, 11, 0, 11,
+ 0, 13, 13, 14, 0, 15, 15, 14,
+ 0, 14, 0, 16, 0, 17, 0, 18,
+ 0, 19, 13, 13, 14, 0, 20, 0,
+ 21, 0, 22, 10, 10, 11, 0, 23,
+ 0, 24, 0, 25, 7, 7, 8, 0,
+ 26, 0, 27, 0, 28, 4, 4, 5,
+ 0, 0, 0, 0, 0, 0, 28, 0,
+ 28, 4, 4, 5, 0, 0, 0, 0,
+ 0, 29, 28, 0, 30, 4, 4, 5,
+ 0, 0, 0, 0, 0, 0, 30, 0,
+ 30, 4, 4, 5, 0, 0, 0, 0,
+ 0, 31, 30, 0, 32, 4, 4, 5,
+ 0, 0, 0, 0, 0, 0, 32, 0,
+ 32, 4, 4, 5, 0, 0, 0, 0,
+ 0, 33, 32, 0, 34, 4, 4, 5,
+ 0, 0, 0, 0, 0, 0, 34, 0,
+ 34, 4, 4, 5, 0, 0, 0, 0,
+ 0, 35, 34, 0, 36, 4, 4, 5,
+ 0, 0, 0, 0, 0, 0, 36, 0,
+ 36, 4, 4, 5, 0, 0, 0, 0,
+ 0, 37, 36, 0, 39, 40, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 39, 38, 41, 38, 42,
+ 42, 43, 38, 44, 44, 43, 38, 43,
+ 38, 45, 45, 46, 38, 47, 47, 46,
+ 38, 46, 38, 48, 48, 49, 38, 50,
+ 50, 49, 38, 49, 38, 51, 51, 52,
+ 38, 53, 53, 52, 38, 52, 38, 54,
+ 38, 55, 38, 56, 38, 57, 51, 51,
+ 52, 38, 58, 38, 59, 38, 60, 48,
+ 48, 49, 38, 61, 38, 62, 38, 63,
+ 45, 45, 46, 38, 64, 38, 65, 38,
+ 66, 42, 42, 43, 38, 38, 38, 38,
+ 38, 38, 66, 38, 66, 42, 42, 43,
+ 38, 38, 38, 38, 38, 67, 66, 38,
+ 68, 42, 42, 43, 38, 38, 38, 38,
+ 38, 38, 68, 38, 68, 42, 42, 43,
+ 38, 38, 38, 38, 38, 69, 68, 38,
+ 70, 42, 42, 43, 38, 38, 38, 38,
+ 38, 38, 70, 38, 70, 42, 42, 43,
+ 38, 38, 38, 38, 38, 71, 70, 38,
+ 72, 42, 42, 43, 38, 38, 38, 38,
+ 38, 38, 72, 38, 72, 42, 42, 43,
+ 38, 38, 38, 38, 38, 73, 72, 38,
+ 74, 42, 42, 43, 38, 38, 38, 38,
+ 38, 38, 74, 38, 74, 42, 42, 43,
+ 38, 38, 38, 38, 38, 75, 74, 38,
+ 77, 78, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 77,
+ 76, 79, 76, 80, 80, 81, 76, 83,
+ 83, 81, 82, 81, 82, 84, 84, 85,
+ 76, 86, 86, 85, 76, 85, 76, 87,
+ 87, 88, 76, 89, 89, 88, 76, 88,
+ 76, 90, 90, 91, 76, 92, 92, 91,
+ 76, 91, 76, 93, 76, 94, 76, 95,
+ 76, 96, 90, 90, 91, 76, 97, 76,
+ 98, 76, 99, 87, 87, 88, 76, 100,
+ 76, 101, 76, 102, 84, 84, 85, 76,
+ 103, 76, 104, 76, 105, 80, 80, 81,
+ 76, 76, 76, 76, 76, 76, 105, 76,
+ 105, 80, 80, 81, 76, 76, 76, 76,
+ 76, 106, 105, 76, 107, 80, 80, 81,
+ 76, 76, 76, 76, 76, 76, 107, 76,
+ 107, 80, 80, 81, 76, 76, 76, 76,
+ 76, 108, 107, 76, 109, 80, 80, 81,
+ 76, 76, 76, 76, 76, 76, 109, 76,
+ 109, 80, 80, 81, 76, 76, 76, 76,
+ 76, 110, 109, 76, 111, 80, 80, 81,
+ 82, 82, 82, 82, 82, 82, 111, 82,
+ 111, 80, 80, 81, 76, 76, 76, 76,
+ 76, 112, 111, 76, 113, 80, 80, 81,
+ 76, 76, 76, 76, 76, 76, 113, 76,
+ 115, 116, 114, 114, 114, 114, 114, 114,
+ 114, 114, 114, 114, 114, 114, 114, 115,
+ 114, 117, 114, 118, 118, 119, 114, 120,
+ 120, 119, 114, 119, 114, 121, 121, 122,
+ 114, 123, 123, 122, 114, 122, 114, 124,
+ 124, 125, 114, 126, 126, 125, 114, 125,
+ 114, 127, 127, 128, 114, 129, 129, 128,
+ 114, 128, 114, 130, 114, 131, 114, 132,
+ 114, 133, 127, 127, 128, 114, 134, 114,
+ 135, 114, 136, 124, 124, 125, 114, 137,
+ 114, 138, 114, 139, 121, 121, 122, 114,
+ 140, 114, 141, 114, 142, 118, 118, 119,
+ 114, 114, 114, 114, 114, 114, 142, 114,
+ 142, 118, 118, 119, 114, 114, 114, 114,
+ 114, 143, 142, 114, 144, 118, 118, 119,
+ 114, 114, 114, 114, 114, 114, 144, 114,
+ 144, 118, 118, 119, 114, 114, 114, 114,
+ 114, 145, 144, 114, 146, 118, 118, 119,
+ 114, 114, 114, 114, 114, 114, 146, 114,
+ 146, 118, 118, 119, 114, 114, 114, 114,
+ 114, 147, 146, 114, 148, 118, 118, 119,
+ 114, 114, 114, 114, 114, 114, 148, 114,
+ 148, 118, 118, 119, 114, 114, 114, 114,
+ 114, 149, 148, 114, 150, 118, 118, 119,
+ 114, 114, 114, 114, 114, 114, 150, 114,
+ 150, 118, 118, 119, 114, 114, 114, 114,
+ 114, 151, 150, 114, 113, 80, 80, 81,
+ 76, 76, 76, 76, 76, 152, 113, 76,
+ 111, 80, 80, 81, 0, 0, 0, 0,
+ 0, 153, 111, 0, 154, 154, 155, 0,
+ 6, 6, 155, 0, 156, 156, 157, 0,
+ 158, 158, 157, 0, 157, 0, 159, 159,
+ 160, 0, 161, 161, 160, 0, 160, 0,
+ 162, 162, 163, 0, 164, 164, 163, 0,
+ 163, 0, 165, 166, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 165, 0, 167, 0, 168, 0, 169,
+ 0, 170, 0, 171, 162, 162, 163, 0,
+ 172, 0, 173, 0, 174, 159, 159, 160,
+ 0, 175, 0, 176, 0, 177, 156, 156,
+ 157, 0, 178, 0, 179, 0, 181, 182,
+ 183, 184, 185, 186, 81, 187, 188, 180,
+ 189, 189, 152, 190, 191, 192, 180, 194,
+ 195, 196, 197, 5, 198, 199, 200, 193,
+ 193, 37, 201, 193, 193, 181, 193, 202,
+ 195, 203, 203, 5, 198, 199, 200, 193,
+ 193, 193, 201, 193, 195, 203, 203, 5,
+ 198, 199, 200, 193, 193, 193, 201, 193,
+ 204, 193, 193, 193, 18, 205, 193, 198,
+ 199, 193, 193, 193, 193, 206, 193, 204,
+ 193, 207, 208, 209, 210, 5, 198, 199,
+ 200, 193, 193, 35, 211, 193, 193, 204,
+ 193, 212, 208, 213, 213, 5, 198, 199,
+ 200, 193, 193, 193, 211, 193, 208, 213,
+ 213, 5, 198, 199, 200, 193, 193, 193,
+ 211, 193, 214, 193, 193, 193, 18, 215,
+ 193, 198, 199, 193, 193, 193, 193, 206,
+ 193, 214, 193, 216, 217, 218, 219, 5,
+ 198, 199, 200, 193, 193, 33, 220, 193,
+ 193, 214, 193, 221, 217, 222, 222, 5,
+ 198, 199, 200, 193, 193, 193, 220, 193,
+ 217, 222, 222, 5, 198, 199, 200, 193,
+ 193, 193, 220, 193, 223, 193, 193, 193,
+ 18, 224, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 223, 193, 225, 226, 227,
+ 228, 5, 198, 199, 200, 193, 193, 31,
+ 229, 193, 193, 223, 193, 230, 226, 231,
+ 231, 5, 198, 199, 200, 193, 193, 193,
+ 229, 193, 226, 231, 231, 5, 198, 199,
+ 200, 193, 193, 193, 229, 193, 232, 193,
+ 193, 193, 18, 233, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 232, 193, 234,
+ 235, 236, 237, 5, 198, 199, 200, 193,
+ 193, 29, 238, 193, 193, 232, 193, 239,
+ 235, 240, 240, 5, 198, 199, 200, 193,
+ 193, 193, 238, 193, 235, 240, 240, 5,
+ 198, 199, 200, 193, 193, 193, 238, 193,
+ 18, 241, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 242, 193, 193, 193, 199,
+ 193, 199, 193, 243, 193, 244, 193, 245,
+ 246, 193, 198, 199, 193, 193, 193, 3,
+ 193, 193, 193, 1, 193, 2, 193, 193,
+ 193, 193, 198, 199, 193, 198, 199, 193,
+ 244, 193, 193, 193, 193, 198, 199, 193,
+ 244, 193, 245, 193, 193, 198, 199, 193,
+ 193, 193, 3, 193, 18, 193, 247, 247,
+ 5, 198, 199, 193, 193, 193, 193, 206,
+ 193, 248, 27, 249, 250, 8, 198, 199,
+ 193, 193, 193, 193, 206, 193, 27, 249,
+ 250, 8, 198, 199, 193, 193, 193, 193,
+ 206, 193, 249, 249, 8, 198, 199, 193,
+ 193, 193, 193, 206, 193, 251, 24, 252,
+ 253, 11, 198, 199, 193, 193, 193, 193,
+ 206, 193, 24, 252, 253, 11, 198, 199,
+ 193, 193, 193, 193, 206, 193, 252, 252,
+ 11, 198, 199, 193, 193, 193, 193, 206,
+ 193, 254, 21, 255, 256, 14, 198, 199,
+ 193, 193, 193, 193, 206, 193, 21, 255,
+ 256, 14, 198, 199, 193, 193, 193, 193,
+ 206, 193, 255, 255, 14, 198, 199, 193,
+ 193, 193, 193, 206, 193, 257, 18, 193,
+ 258, 193, 198, 199, 193, 193, 193, 193,
+ 206, 193, 18, 193, 258, 193, 198, 199,
+ 193, 193, 193, 193, 206, 193, 259, 193,
+ 198, 199, 193, 193, 193, 193, 206, 193,
+ 18, 193, 193, 193, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 235, 240, 240,
+ 5, 198, 199, 193, 193, 193, 193, 238,
+ 193, 1, 2, 193, 193, 18, 241, 193,
+ 198, 199, 193, 193, 193, 193, 206, 193,
+ 1, 193, 234, 235, 240, 240, 5, 198,
+ 199, 200, 193, 193, 193, 238, 193, 234,
+ 235, 236, 240, 5, 198, 199, 200, 193,
+ 193, 29, 238, 193, 232, 193, 260, 193,
+ 247, 247, 5, 198, 199, 193, 193, 193,
+ 193, 206, 193, 232, 193, 232, 193, 193,
+ 193, 193, 193, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 232, 193, 232, 193,
+ 193, 193, 193, 261, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 232, 193, 232,
+ 193, 260, 193, 193, 193, 193, 198, 199,
+ 193, 193, 193, 193, 206, 193, 232, 193,
+ 232, 2, 193, 193, 18, 233, 193, 198,
+ 199, 193, 193, 193, 193, 206, 193, 232,
+ 193, 225, 226, 231, 231, 5, 198, 199,
+ 200, 193, 193, 193, 229, 193, 225, 226,
+ 227, 231, 5, 198, 199, 200, 193, 193,
+ 31, 229, 193, 223, 193, 262, 193, 247,
+ 247, 5, 198, 199, 193, 193, 193, 193,
+ 206, 193, 223, 193, 223, 193, 193, 193,
+ 193, 193, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 223, 193, 223, 193, 193,
+ 193, 193, 263, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 223, 193, 223, 193,
+ 262, 193, 193, 193, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 223, 193, 223,
+ 2, 193, 193, 18, 224, 193, 198, 199,
+ 193, 193, 193, 193, 206, 193, 223, 193,
+ 216, 217, 222, 222, 5, 198, 199, 200,
+ 193, 193, 193, 220, 193, 216, 217, 218,
+ 222, 5, 198, 199, 200, 193, 193, 33,
+ 220, 193, 214, 193, 264, 193, 247, 247,
+ 5, 198, 199, 193, 193, 193, 193, 206,
+ 193, 214, 193, 214, 193, 193, 193, 193,
+ 193, 193, 198, 199, 193, 193, 193, 193,
+ 206, 193, 214, 193, 214, 193, 193, 193,
+ 193, 265, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 214, 193, 214, 193, 264,
+ 193, 193, 193, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 214, 193, 214, 2,
+ 193, 193, 18, 215, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 214, 193, 207,
+ 208, 213, 213, 5, 198, 199, 200, 193,
+ 193, 193, 211, 193, 207, 208, 209, 213,
+ 5, 198, 199, 200, 193, 193, 35, 211,
+ 193, 204, 193, 266, 193, 247, 247, 5,
+ 198, 199, 193, 193, 193, 193, 206, 193,
+ 204, 193, 204, 193, 193, 193, 193, 193,
+ 193, 198, 199, 193, 193, 193, 193, 206,
+ 193, 204, 193, 204, 193, 193, 193, 193,
+ 267, 193, 198, 199, 193, 193, 193, 193,
+ 206, 193, 204, 193, 204, 193, 266, 193,
+ 193, 193, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 204, 193, 204, 2, 193,
+ 193, 18, 205, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 204, 193, 194, 195,
+ 203, 203, 5, 198, 199, 200, 193, 193,
+ 193, 201, 193, 194, 195, 196, 203, 5,
+ 198, 199, 200, 193, 193, 37, 201, 193,
+ 269, 270, 271, 272, 43, 273, 274, 268,
+ 268, 268, 75, 275, 268, 276, 270, 277,
+ 272, 43, 273, 274, 268, 268, 268, 268,
+ 275, 268, 270, 277, 272, 43, 273, 274,
+ 268, 268, 268, 268, 275, 268, 278, 268,
+ 268, 268, 56, 279, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 278, 268, 281,
+ 282, 283, 284, 43, 273, 274, 268, 268,
+ 268, 73, 285, 268, 268, 278, 268, 286,
+ 282, 287, 287, 43, 273, 274, 268, 268,
+ 268, 268, 285, 268, 282, 287, 287, 43,
+ 273, 274, 268, 268, 268, 268, 285, 268,
+ 288, 268, 268, 268, 56, 289, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 288,
+ 268, 290, 291, 292, 293, 43, 273, 274,
+ 268, 268, 268, 71, 294, 268, 268, 288,
+ 268, 295, 291, 296, 296, 43, 273, 274,
+ 268, 268, 268, 268, 294, 268, 291, 296,
+ 296, 43, 273, 274, 268, 268, 268, 268,
+ 294, 268, 297, 268, 268, 268, 56, 298,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 297, 268, 299, 300, 301, 302, 43,
+ 273, 274, 268, 268, 268, 69, 303, 268,
+ 268, 297, 268, 304, 300, 305, 305, 43,
+ 273, 274, 268, 268, 268, 268, 303, 268,
+ 300, 305, 305, 43, 273, 274, 268, 268,
+ 268, 268, 303, 268, 306, 268, 268, 268,
+ 56, 307, 268, 273, 274, 268, 268, 268,
+ 268, 280, 268, 306, 268, 308, 309, 310,
+ 311, 43, 273, 274, 268, 268, 268, 67,
+ 312, 268, 268, 306, 268, 313, 309, 314,
+ 314, 43, 273, 274, 268, 268, 268, 268,
+ 312, 268, 309, 314, 314, 43, 273, 274,
+ 268, 268, 268, 268, 312, 268, 56, 315,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 316, 268, 268, 268, 274, 268, 274,
+ 268, 317, 268, 318, 268, 319, 320, 268,
+ 273, 274, 268, 268, 268, 41, 268, 268,
+ 268, 39, 268, 40, 268, 268, 268, 268,
+ 273, 274, 268, 273, 274, 268, 318, 268,
+ 268, 268, 268, 273, 274, 268, 318, 268,
+ 319, 268, 268, 273, 274, 268, 268, 268,
+ 41, 268, 56, 268, 321, 321, 43, 273,
+ 274, 268, 268, 268, 268, 280, 268, 322,
+ 65, 323, 324, 46, 273, 274, 268, 268,
+ 268, 268, 280, 268, 65, 323, 324, 46,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 323, 323, 46, 273, 274, 268, 268, 268,
+ 268, 280, 268, 325, 62, 326, 327, 49,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 62, 326, 327, 49, 273, 274, 268, 268,
+ 268, 268, 280, 268, 326, 326, 49, 273,
+ 274, 268, 268, 268, 268, 280, 268, 328,
+ 59, 329, 330, 52, 273, 274, 268, 268,
+ 268, 268, 280, 268, 59, 329, 330, 52,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 329, 329, 52, 273, 274, 268, 268, 268,
+ 268, 280, 268, 331, 56, 268, 332, 268,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 56, 268, 332, 268, 273, 274, 268, 268,
+ 268, 268, 280, 268, 333, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 56, 268,
+ 268, 268, 268, 273, 274, 268, 268, 268,
+ 268, 280, 268, 39, 40, 268, 268, 56,
+ 315, 268, 273, 274, 268, 268, 268, 268,
+ 280, 268, 39, 268, 308, 309, 314, 314,
+ 43, 273, 274, 268, 268, 268, 268, 312,
+ 268, 308, 309, 310, 314, 43, 273, 274,
+ 268, 268, 268, 67, 312, 268, 306, 268,
+ 334, 268, 321, 321, 43, 273, 274, 268,
+ 268, 268, 268, 280, 268, 306, 268, 306,
+ 268, 268, 268, 268, 268, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 306, 268,
+ 306, 268, 268, 268, 268, 335, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 306,
+ 268, 306, 268, 334, 268, 268, 268, 268,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 306, 268, 306, 40, 268, 268, 56, 307,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 306, 268, 299, 300, 305, 305, 43,
+ 273, 274, 268, 268, 268, 268, 303, 268,
+ 299, 300, 301, 305, 43, 273, 274, 268,
+ 268, 268, 69, 303, 268, 297, 268, 336,
+ 268, 321, 321, 43, 273, 274, 268, 268,
+ 268, 268, 280, 268, 297, 268, 297, 268,
+ 268, 268, 268, 268, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 297, 268, 297,
+ 268, 268, 268, 268, 337, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 297, 268,
+ 297, 268, 336, 268, 268, 268, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 297,
+ 268, 297, 40, 268, 268, 56, 298, 268,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 297, 268, 290, 291, 296, 296, 43, 273,
+ 274, 268, 268, 268, 268, 294, 268, 290,
+ 291, 292, 296, 43, 273, 274, 268, 268,
+ 268, 71, 294, 268, 288, 268, 338, 268,
+ 321, 321, 43, 273, 274, 268, 268, 268,
+ 268, 280, 268, 288, 268, 288, 268, 268,
+ 268, 268, 268, 268, 273, 274, 268, 268,
+ 268, 268, 280, 268, 288, 268, 288, 268,
+ 268, 268, 268, 339, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 288, 268, 288,
+ 268, 338, 268, 268, 268, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 288, 268,
+ 288, 40, 268, 268, 56, 289, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 288,
+ 268, 281, 282, 287, 287, 43, 273, 274,
+ 268, 268, 268, 268, 285, 268, 281, 282,
+ 283, 287, 43, 273, 274, 268, 268, 268,
+ 73, 285, 268, 278, 268, 340, 268, 321,
+ 321, 43, 273, 274, 268, 268, 268, 268,
+ 280, 268, 278, 268, 278, 268, 268, 268,
+ 268, 268, 268, 273, 274, 268, 268, 268,
+ 268, 280, 268, 278, 268, 278, 268, 268,
+ 268, 268, 341, 268, 273, 274, 268, 268,
+ 268, 268, 280, 268, 278, 268, 278, 268,
+ 340, 268, 268, 268, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 278, 268, 74,
+ 42, 42, 43, 268, 268, 268, 268, 268,
+ 268, 74, 268, 278, 40, 268, 268, 56,
+ 279, 268, 273, 274, 268, 268, 268, 268,
+ 280, 268, 278, 268, 269, 270, 277, 272,
+ 43, 273, 274, 268, 268, 268, 268, 275,
+ 268, 343, 184, 344, 344, 81, 187, 188,
+ 342, 342, 342, 342, 190, 342, 184, 344,
+ 344, 81, 187, 188, 342, 342, 342, 342,
+ 190, 342, 345, 342, 342, 342, 95, 346,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 345, 342, 348, 349, 350, 351, 81,
+ 187, 188, 342, 342, 342, 112, 352, 342,
+ 342, 345, 342, 353, 349, 354, 354, 81,
+ 187, 188, 342, 342, 342, 342, 352, 342,
+ 349, 354, 354, 81, 187, 188, 342, 342,
+ 342, 342, 352, 342, 355, 342, 342, 342,
+ 95, 356, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 355, 342, 357, 358, 359,
+ 360, 81, 187, 188, 342, 342, 342, 110,
+ 361, 342, 342, 355, 342, 362, 358, 363,
+ 363, 81, 187, 188, 342, 342, 342, 342,
+ 361, 342, 358, 363, 363, 81, 187, 188,
+ 342, 342, 342, 342, 361, 342, 364, 342,
+ 342, 342, 95, 365, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 364, 342, 366,
+ 367, 368, 369, 81, 187, 188, 342, 342,
+ 342, 108, 370, 342, 342, 364, 342, 371,
+ 367, 372, 372, 81, 187, 188, 342, 342,
+ 342, 342, 370, 342, 367, 372, 372, 81,
+ 187, 188, 342, 342, 342, 342, 370, 342,
+ 373, 342, 342, 342, 95, 374, 342, 187,
+ 188, 342, 342, 342, 342, 347, 342, 373,
+ 342, 375, 376, 377, 378, 81, 187, 188,
+ 342, 342, 342, 106, 379, 342, 342, 373,
+ 342, 380, 376, 381, 381, 81, 187, 188,
+ 342, 342, 342, 342, 379, 342, 376, 381,
+ 381, 81, 187, 188, 342, 342, 342, 342,
+ 379, 342, 95, 382, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 383, 342, 342,
+ 342, 188, 342, 188, 342, 384, 342, 385,
+ 342, 386, 387, 342, 187, 188, 342, 342,
+ 342, 79, 342, 342, 342, 77, 342, 78,
+ 342, 342, 342, 342, 187, 188, 342, 187,
+ 188, 342, 385, 342, 342, 342, 342, 187,
+ 188, 342, 385, 342, 386, 342, 342, 187,
+ 188, 342, 342, 342, 79, 342, 95, 342,
+ 388, 388, 81, 187, 188, 342, 342, 342,
+ 342, 347, 342, 389, 104, 390, 391, 85,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 104, 390, 391, 85, 187, 188, 342, 342,
+ 342, 342, 347, 342, 390, 390, 85, 187,
+ 188, 342, 342, 342, 342, 347, 342, 392,
+ 101, 393, 394, 88, 187, 188, 342, 342,
+ 342, 342, 347, 342, 101, 393, 394, 88,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 393, 393, 88, 187, 188, 342, 342, 342,
+ 342, 347, 342, 395, 98, 396, 397, 91,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 98, 396, 397, 91, 187, 188, 342, 342,
+ 342, 342, 347, 342, 396, 396, 91, 187,
+ 188, 342, 342, 342, 342, 347, 342, 398,
+ 95, 342, 399, 342, 187, 188, 342, 342,
+ 342, 342, 347, 342, 95, 342, 399, 342,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 400, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 95, 342, 342, 342, 342, 187,
+ 188, 342, 342, 342, 342, 347, 342, 77,
+ 78, 342, 342, 95, 382, 342, 187, 188,
+ 342, 342, 342, 342, 347, 342, 77, 342,
+ 375, 376, 381, 381, 81, 187, 188, 342,
+ 342, 342, 342, 379, 342, 375, 376, 377,
+ 381, 81, 187, 188, 342, 342, 342, 106,
+ 379, 342, 373, 342, 401, 342, 388, 388,
+ 81, 187, 188, 342, 342, 342, 342, 347,
+ 342, 373, 342, 373, 342, 342, 342, 342,
+ 342, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 373, 342, 373, 342, 342, 342,
+ 342, 402, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 373, 342, 373, 342, 401,
+ 342, 342, 342, 342, 187, 188, 342, 342,
+ 342, 342, 347, 342, 373, 342, 373, 78,
+ 342, 342, 95, 374, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 373, 342, 366,
+ 367, 372, 372, 81, 187, 188, 342, 342,
+ 342, 342, 370, 342, 366, 367, 368, 372,
+ 81, 187, 188, 342, 342, 342, 108, 370,
+ 342, 364, 342, 403, 342, 388, 388, 81,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 364, 342, 364, 342, 342, 342, 342, 342,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 364, 342, 364, 342, 342, 342, 342,
+ 404, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 364, 342, 364, 342, 403, 342,
+ 342, 342, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 364, 342, 364, 78, 342,
+ 342, 95, 365, 342, 187, 188, 342, 342,
+ 342, 342, 347, 342, 364, 342, 357, 358,
+ 363, 363, 81, 187, 188, 342, 342, 342,
+ 342, 361, 342, 357, 358, 359, 363, 81,
+ 187, 188, 342, 342, 342, 110, 361, 342,
+ 355, 342, 405, 342, 388, 388, 81, 187,
+ 188, 342, 342, 342, 342, 347, 342, 355,
+ 342, 355, 342, 342, 342, 342, 342, 342,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 355, 342, 355, 342, 342, 342, 342, 406,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 355, 342, 355, 342, 405, 342, 342,
+ 342, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 355, 342, 355, 78, 342, 342,
+ 95, 356, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 355, 342, 348, 349, 354,
+ 354, 81, 187, 188, 342, 342, 342, 342,
+ 352, 342, 348, 349, 350, 354, 81, 187,
+ 188, 342, 342, 342, 112, 352, 342, 345,
+ 342, 407, 342, 388, 388, 81, 187, 188,
+ 342, 342, 342, 342, 347, 342, 345, 342,
+ 345, 342, 342, 342, 342, 342, 342, 187,
+ 188, 342, 342, 342, 342, 347, 342, 345,
+ 342, 345, 342, 342, 342, 342, 408, 342,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 345, 342, 345, 342, 407, 342, 342, 342,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 345, 342, 345, 78, 342, 342, 95,
+ 346, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 345, 342, 113, 80, 80, 81,
+ 409, 409, 409, 409, 409, 152, 113, 409,
+ 183, 184, 344, 344, 81, 187, 188, 342,
+ 342, 342, 342, 190, 342, 113, 80, 80,
+ 81, 409, 409, 409, 409, 409, 409, 113,
+ 409, 411, 412, 413, 414, 119, 415, 416,
+ 410, 410, 410, 151, 417, 410, 418, 412,
+ 414, 414, 119, 415, 416, 410, 410, 410,
+ 410, 417, 410, 412, 414, 414, 119, 415,
+ 416, 410, 410, 410, 410, 417, 410, 419,
+ 410, 410, 410, 132, 420, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 419, 410,
+ 422, 423, 424, 425, 119, 415, 416, 410,
+ 410, 410, 149, 426, 410, 410, 419, 410,
+ 427, 423, 428, 428, 119, 415, 416, 410,
+ 410, 410, 410, 426, 410, 423, 428, 428,
+ 119, 415, 416, 410, 410, 410, 410, 426,
+ 410, 429, 410, 410, 410, 132, 430, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 429, 410, 431, 432, 433, 434, 119, 415,
+ 416, 410, 410, 410, 147, 435, 410, 410,
+ 429, 410, 436, 432, 437, 437, 119, 415,
+ 416, 410, 410, 410, 410, 435, 410, 432,
+ 437, 437, 119, 415, 416, 410, 410, 410,
+ 410, 435, 410, 438, 410, 410, 410, 132,
+ 439, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 438, 410, 440, 441, 442, 443,
+ 119, 415, 416, 410, 410, 410, 145, 444,
+ 410, 410, 438, 410, 445, 441, 446, 446,
+ 119, 415, 416, 410, 410, 410, 410, 444,
+ 410, 441, 446, 446, 119, 415, 416, 410,
+ 410, 410, 410, 444, 410, 447, 410, 410,
+ 410, 132, 448, 410, 415, 416, 410, 410,
+ 410, 410, 421, 410, 447, 410, 449, 450,
+ 451, 452, 119, 415, 416, 410, 410, 410,
+ 143, 453, 410, 410, 447, 410, 454, 450,
+ 455, 455, 119, 415, 416, 410, 410, 410,
+ 410, 453, 410, 450, 455, 455, 119, 415,
+ 416, 410, 410, 410, 410, 453, 410, 132,
+ 456, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 457, 410, 410, 410, 416, 410,
+ 416, 410, 458, 410, 459, 410, 460, 461,
+ 410, 415, 416, 410, 410, 410, 117, 410,
+ 410, 410, 115, 410, 116, 410, 410, 410,
+ 410, 415, 416, 410, 415, 416, 410, 459,
+ 410, 410, 410, 410, 415, 416, 410, 459,
+ 410, 460, 410, 410, 415, 416, 410, 410,
+ 410, 117, 410, 132, 410, 462, 462, 119,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 463, 141, 464, 465, 122, 415, 416, 410,
+ 410, 410, 410, 421, 410, 141, 464, 465,
+ 122, 415, 416, 410, 410, 410, 410, 421,
+ 410, 464, 464, 122, 415, 416, 410, 410,
+ 410, 410, 421, 410, 466, 138, 467, 468,
+ 125, 415, 416, 410, 410, 410, 410, 421,
+ 410, 138, 467, 468, 125, 415, 416, 410,
+ 410, 410, 410, 421, 410, 467, 467, 125,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 469, 135, 470, 471, 128, 415, 416, 410,
+ 410, 410, 410, 421, 410, 135, 470, 471,
+ 128, 415, 416, 410, 410, 410, 410, 421,
+ 410, 470, 470, 128, 415, 416, 410, 410,
+ 410, 410, 421, 410, 472, 132, 410, 473,
+ 410, 415, 416, 410, 410, 410, 410, 421,
+ 410, 132, 410, 473, 410, 415, 416, 410,
+ 410, 410, 410, 421, 410, 474, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 132,
+ 410, 410, 410, 410, 415, 416, 410, 410,
+ 410, 410, 421, 410, 115, 116, 410, 410,
+ 132, 456, 410, 415, 416, 410, 410, 410,
+ 410, 421, 410, 115, 410, 449, 450, 455,
+ 455, 119, 415, 416, 410, 410, 410, 410,
+ 453, 410, 449, 450, 451, 455, 119, 415,
+ 416, 410, 410, 410, 143, 453, 410, 447,
+ 410, 475, 410, 462, 462, 119, 415, 416,
+ 410, 410, 410, 410, 421, 410, 447, 410,
+ 447, 410, 410, 410, 410, 410, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 447,
+ 410, 447, 410, 410, 410, 410, 476, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 447, 410, 447, 410, 475, 410, 410, 410,
+ 410, 415, 416, 410, 410, 410, 410, 421,
+ 410, 447, 410, 447, 116, 410, 410, 132,
+ 448, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 447, 410, 440, 441, 446, 446,
+ 119, 415, 416, 410, 410, 410, 410, 444,
+ 410, 440, 441, 442, 446, 119, 415, 416,
+ 410, 410, 410, 145, 444, 410, 438, 410,
+ 477, 410, 462, 462, 119, 415, 416, 410,
+ 410, 410, 410, 421, 410, 438, 410, 438,
+ 410, 410, 410, 410, 410, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 438, 410,
+ 438, 410, 410, 410, 410, 478, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 438,
+ 410, 438, 410, 477, 410, 410, 410, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 438, 410, 438, 116, 410, 410, 132, 439,
+ 410, 415, 416, 410, 410, 410, 410, 421,
+ 410, 438, 410, 431, 432, 437, 437, 119,
+ 415, 416, 410, 410, 410, 410, 435, 410,
+ 431, 432, 433, 437, 119, 415, 416, 410,
+ 410, 410, 147, 435, 410, 429, 410, 479,
+ 410, 462, 462, 119, 415, 416, 410, 410,
+ 410, 410, 421, 410, 429, 410, 429, 410,
+ 410, 410, 410, 410, 410, 415, 416, 410,
+ 410, 410, 410, 421, 410, 429, 410, 429,
+ 410, 410, 410, 410, 480, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 429, 410,
+ 429, 410, 479, 410, 410, 410, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 429,
+ 410, 429, 116, 410, 410, 132, 430, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 429, 410, 422, 423, 428, 428, 119, 415,
+ 416, 410, 410, 410, 410, 426, 410, 422,
+ 423, 424, 428, 119, 415, 416, 410, 410,
+ 410, 149, 426, 410, 419, 410, 481, 410,
+ 462, 462, 119, 415, 416, 410, 410, 410,
+ 410, 421, 410, 419, 410, 419, 410, 410,
+ 410, 410, 410, 410, 415, 416, 410, 410,
+ 410, 410, 421, 410, 419, 410, 419, 410,
+ 410, 410, 410, 482, 410, 415, 416, 410,
+ 410, 410, 410, 421, 410, 419, 410, 419,
+ 410, 481, 410, 410, 410, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 419, 410,
+ 419, 116, 410, 410, 132, 420, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 419,
+ 410, 411, 412, 414, 414, 119, 415, 416,
+ 410, 410, 410, 410, 417, 410, 181, 182,
+ 183, 184, 483, 344, 81, 187, 188, 342,
+ 189, 189, 152, 190, 342, 181, 342, 194,
+ 484, 196, 197, 5, 198, 199, 200, 193,
+ 193, 37, 201, 193, 193, 181, 193, 204,
+ 182, 183, 184, 485, 486, 81, 487, 488,
+ 193, 189, 189, 152, 489, 193, 204, 193,
+ 113, 80, 80, 81, 198, 199, 193, 193,
+ 193, 152, 490, 193, 491, 2, 342, 342,
+ 342, 408, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 491, 342, 492, 349, 493,
+ 494, 81, 487, 488, 193, 193, 193, 153,
+ 352, 193, 193, 491, 193, 495, 349, 354,
+ 354, 81, 487, 488, 193, 193, 193, 193,
+ 352, 193, 349, 354, 354, 81, 487, 488,
+ 193, 193, 193, 193, 352, 193, 496, 193,
+ 193, 193, 488, 193, 488, 193, 243, 193,
+ 492, 349, 354, 354, 81, 487, 488, 193,
+ 193, 193, 193, 352, 193, 492, 349, 493,
+ 354, 81, 487, 488, 193, 193, 193, 153,
+ 352, 193, 204, 193, 266, 113, 497, 497,
+ 155, 198, 199, 193, 193, 193, 193, 490,
+ 193, 204, 193, 498, 179, 499, 500, 157,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 179, 499, 500, 157, 487, 488, 193, 193,
+ 193, 193, 501, 193, 499, 499, 157, 487,
+ 488, 193, 193, 193, 193, 501, 193, 502,
+ 176, 503, 504, 160, 487, 488, 193, 193,
+ 193, 193, 501, 193, 176, 503, 504, 160,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 503, 503, 160, 487, 488, 193, 193, 193,
+ 193, 501, 193, 505, 173, 506, 507, 163,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 173, 506, 507, 163, 487, 488, 193, 193,
+ 193, 193, 501, 193, 506, 506, 163, 487,
+ 488, 193, 193, 193, 193, 501, 193, 508,
+ 170, 193, 509, 193, 487, 488, 193, 193,
+ 193, 193, 501, 193, 170, 193, 509, 193,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 510, 193, 511, 512, 193, 487, 488, 193,
+ 193, 193, 167, 193, 193, 193, 165, 193,
+ 166, 193, 193, 193, 193, 487, 488, 193,
+ 487, 488, 193, 510, 193, 193, 193, 193,
+ 487, 488, 193, 510, 193, 511, 193, 193,
+ 487, 488, 193, 193, 193, 167, 193, 491,
+ 166, 342, 342, 95, 346, 342, 187, 188,
+ 342, 342, 342, 342, 347, 342, 491, 342,
+ 0
+};
+
+static const short _indic_syllable_machine_trans_targs[] = {
+ 170, 195, 197, 198, 3, 201, 4, 6,
+ 204, 7, 9, 207, 10, 12, 210, 13,
+ 15, 16, 191, 18, 19, 209, 21, 22,
+ 206, 24, 25, 203, 212, 216, 220, 223,
+ 227, 230, 234, 237, 241, 244, 170, 270,
+ 272, 273, 39, 276, 40, 42, 279, 43,
+ 45, 282, 46, 48, 285, 49, 51, 52,
+ 266, 54, 55, 284, 57, 58, 281, 60,
+ 61, 278, 287, 290, 294, 297, 301, 304,
+ 308, 311, 315, 319, 170, 343, 345, 346,
+ 75, 349, 170, 76, 78, 352, 79, 81,
+ 355, 82, 84, 358, 85, 87, 88, 339,
+ 90, 91, 357, 93, 94, 354, 96, 97,
+ 351, 360, 363, 367, 370, 374, 377, 381,
+ 384, 388, 170, 418, 420, 421, 110, 424,
+ 111, 113, 427, 114, 116, 430, 117, 119,
+ 433, 120, 122, 123, 414, 125, 126, 432,
+ 128, 129, 429, 131, 132, 426, 435, 438,
+ 442, 445, 449, 452, 456, 459, 463, 466,
+ 392, 478, 146, 481, 148, 484, 149, 151,
+ 487, 152, 154, 490, 155, 493, 495, 496,
+ 159, 160, 492, 162, 163, 489, 165, 166,
+ 486, 168, 169, 483, 170, 171, 246, 320,
+ 322, 391, 393, 340, 342, 394, 390, 467,
+ 468, 170, 172, 174, 35, 245, 192, 194,
+ 214, 243, 173, 34, 175, 239, 0, 176,
+ 178, 33, 238, 236, 177, 32, 179, 232,
+ 180, 182, 31, 231, 229, 181, 30, 183,
+ 225, 184, 186, 29, 224, 222, 185, 28,
+ 187, 218, 188, 190, 27, 217, 215, 189,
+ 26, 200, 193, 170, 196, 1, 199, 2,
+ 202, 5, 23, 205, 8, 20, 208, 11,
+ 17, 211, 14, 213, 219, 221, 226, 228,
+ 233, 235, 240, 242, 170, 247, 249, 71,
+ 317, 267, 269, 318, 248, 70, 250, 313,
+ 36, 251, 253, 69, 312, 310, 252, 68,
+ 254, 306, 255, 257, 67, 305, 303, 256,
+ 66, 258, 299, 259, 261, 65, 298, 296,
+ 260, 64, 262, 292, 263, 265, 63, 291,
+ 289, 264, 62, 275, 268, 170, 271, 37,
+ 274, 38, 277, 41, 59, 280, 44, 56,
+ 283, 47, 53, 286, 50, 288, 293, 295,
+ 300, 302, 307, 309, 314, 316, 170, 321,
+ 106, 323, 386, 72, 324, 326, 105, 385,
+ 383, 325, 104, 327, 379, 328, 330, 103,
+ 378, 376, 329, 102, 331, 372, 332, 334,
+ 101, 371, 369, 333, 100, 335, 365, 336,
+ 338, 99, 364, 362, 337, 98, 348, 341,
+ 170, 344, 73, 347, 74, 350, 77, 95,
+ 353, 80, 92, 356, 83, 89, 359, 86,
+ 361, 366, 368, 373, 375, 380, 382, 387,
+ 389, 170, 170, 395, 397, 142, 141, 415,
+ 417, 465, 396, 398, 461, 107, 399, 401,
+ 140, 460, 458, 400, 139, 402, 454, 403,
+ 405, 138, 453, 451, 404, 137, 406, 447,
+ 407, 409, 136, 446, 444, 408, 135, 410,
+ 440, 411, 413, 134, 439, 437, 412, 133,
+ 423, 416, 170, 419, 108, 422, 109, 425,
+ 112, 130, 428, 115, 127, 431, 118, 124,
+ 434, 121, 436, 441, 443, 448, 450, 455,
+ 457, 462, 464, 143, 469, 470, 480, 475,
+ 477, 498, 471, 472, 473, 144, 479, 474,
+ 476, 145, 482, 147, 167, 156, 485, 150,
+ 164, 488, 153, 161, 491, 158, 494, 157,
+ 497
+};
+
+static const char _indic_syllable_machine_trans_actions[] = {
+ 1, 2, 0, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 3, 2,
+ 0, 0, 0, 2, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 0, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 4, 2, 0, 0,
+ 0, 2, 5, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 0, 0, 2,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 2, 6, 2, 6, 2, 6, 2,
+ 6, 2, 7, 2, 0, 0, 0, 2,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 0, 2, 0, 0, 2,
+ 0, 0, 2, 0, 0, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 6, 8, 0, 2, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 2, 0, 0,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 11, 2, 2, 6,
+ 2, 12, 12, 0, 0, 2, 2, 6,
+ 2, 13, 2, 2, 0, 2, 0, 0,
+ 2, 2, 2, 0, 2, 2, 0, 2,
+ 2, 0, 2, 2, 2, 0, 2, 2,
+ 2, 2, 0, 2, 2, 2, 0, 2,
+ 2, 2, 2, 0, 2, 2, 2, 0,
+ 2, 2, 2, 2, 0, 2, 2, 2,
+ 0, 2, 0, 14, 0, 0, 2, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 0, 2, 0, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 15, 2, 2, 0,
+ 2, 0, 0, 2, 2, 0, 2, 2,
+ 0, 2, 2, 0, 2, 2, 2, 0,
+ 2, 2, 2, 2, 0, 2, 2, 2,
+ 0, 2, 2, 2, 2, 0, 2, 2,
+ 2, 0, 2, 2, 2, 2, 0, 2,
+ 2, 2, 0, 2, 0, 16, 0, 0,
+ 2, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 17, 6,
+ 0, 6, 6, 0, 6, 2, 0, 6,
+ 2, 6, 0, 6, 6, 6, 2, 0,
+ 6, 2, 6, 0, 6, 6, 6, 2,
+ 0, 6, 2, 6, 0, 6, 6, 6,
+ 2, 0, 6, 2, 6, 0, 6, 0,
+ 18, 0, 0, 2, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 19, 20, 2, 2, 0, 0, 0,
+ 0, 2, 2, 2, 2, 0, 2, 2,
+ 0, 2, 2, 2, 0, 2, 2, 2,
+ 2, 0, 2, 2, 2, 0, 2, 2,
+ 2, 2, 0, 2, 2, 2, 0, 2,
+ 2, 2, 2, 0, 2, 2, 2, 0,
+ 2, 0, 21, 0, 0, 2, 0, 2,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 0, 0, 8, 2, 0,
+ 0, 2, 2, 8, 8, 0, 8, 8,
+ 0, 0, 2, 0, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 0,
+ 2
+};
+
+static const char _indic_syllable_machine_to_state_actions[] = {
+ 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, 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, 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, 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,
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 9, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+static const char _indic_syllable_machine_from_state_actions[] = {
+ 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, 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, 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, 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,
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+static const short _indic_syllable_machine_eof_trans[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39,
+ 77, 77, 77, 83, 83, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77,
+ 83, 77, 77, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 77,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 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,
+ 194, 194, 194, 194, 194, 194, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 410,
+ 343, 410, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 343, 194, 194, 194, 343,
+ 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, 343
+};
+
+static const int indic_syllable_machine_start = 170;
+static const int indic_syllable_machine_first_final = 170;
+static const int indic_syllable_machine_error = -1;
+
+static const int indic_syllable_machine_en_main = 170;
+
+
+#line 36 "hb-ot-shape-complex-indic-machine.rl"
+
+
+
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+ for (unsigned int i = last; i < p+1; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ last = p+1; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 1273 "hb-ot-shape-complex-indic-machine.hh"
+ {
+ cs = indic_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 112 "hb-ot-shape-complex-indic-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int last = 0;
+ unsigned int syllable_serial = 1;
+
+#line 1290 "hb-ot-shape-complex-indic-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const short *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _indic_syllable_machine_from_state_actions[cs] ) {
+ case 10:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 1304 "hb-ot-shape-complex-indic-machine.hh"
+ }
+
+ _keys = _indic_syllable_machine_trans_keys + (cs<<1);
+ _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs];
+
+ _slen = _indic_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) &&
+ ( info[p].indic_category()) <= _keys[1] ?
+ ( info[p].indic_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _indic_syllable_machine_trans_targs[_trans];
+
+ if ( _indic_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _indic_syllable_machine_trans_actions[_trans] ) {
+ case 2:
+#line 1 "NONE"
+ {te = p+1;}
+ break;
+ case 14:
+#line 83 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (consonant_syllable); }}
+ break;
+ case 16:
+#line 84 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (vowel_syllable); }}
+ break;
+ case 21:
+#line 85 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (standalone_cluster); }}
+ break;
+ case 18:
+#line 86 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (broken_cluster); }}
+ break;
+ case 11:
+#line 87 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (non_indic_cluster); }}
+ break;
+ case 13:
+#line 83 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (consonant_syllable); }}
+ break;
+ case 15:
+#line 84 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (vowel_syllable); }}
+ break;
+ case 20:
+#line 85 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (standalone_cluster); }}
+ break;
+ case 17:
+#line 86 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (broken_cluster); }}
+ break;
+ case 19:
+#line 87 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (non_indic_cluster); }}
+ break;
+ case 1:
+#line 83 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
+ break;
+ case 3:
+#line 84 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
+ break;
+ case 7:
+#line 85 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
+ break;
+ case 4:
+#line 86 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
+ break;
+ case 5:
+#line 1 "NONE"
+ { switch( act ) {
+ case 1:
+ {{p = ((te))-1;} found_syllable (consonant_syllable); }
+ break;
+ case 4:
+ {{p = ((te))-1;} found_syllable (broken_cluster); }
+ break;
+ case 5:
+ {{p = ((te))-1;} found_syllable (non_indic_cluster); }
+ break;
+ }
+ }
+ break;
+ case 8:
+#line 1 "NONE"
+ {te = p+1;}
+#line 83 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 1;}
+ break;
+ case 6:
+#line 1 "NONE"
+ {te = p+1;}
+#line 86 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 4;}
+ break;
+ case 12:
+#line 1 "NONE"
+ {te = p+1;}
+#line 87 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 5;}
+ break;
+#line 1415 "hb-ot-shape-complex-indic-machine.hh"
+ }
+
+_again:
+ switch ( _indic_syllable_machine_to_state_actions[cs] ) {
+ case 9:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 1424 "hb-ot-shape-complex-indic-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _indic_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _indic_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 121 "hb-ot-shape-complex-indic-machine.rl"
+
+}
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
new file mode 100644
index 0000000000..39268b1453
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh" /* XXX Remove */
+
+
+#define INDIC_TABLE_ELEMENT_TYPE uint16_t
+
+/* Cateories used in the OpenType spec:
+ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
+ */
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum indic_category_t {
+ OT_X = 0,
+ OT_C,
+ OT_V,
+ OT_N,
+ OT_H,
+ OT_ZWNJ,
+ OT_ZWJ,
+ OT_M,
+ OT_SM,
+ OT_VD,
+ OT_A,
+ OT_NBSP,
+ OT_DOTTEDCIRCLE, /* Not in the spec, but special in Uniscribe. /Very very/ special! */
+ OT_RS, /* Register Shifter, used in Khmer OT spec */
+ OT_Coeng,
+ OT_Repha,
+ OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
+ OT_CM
+};
+
+/* Visual positions in a syllable from left to right. */
+enum indic_position_t {
+ POS_START,
+
+ POS_RA_TO_BECOME_REPH,
+ POS_PRE_M,
+ POS_PRE_C,
+
+ POS_BASE_C,
+ POS_AFTER_MAIN,
+
+ POS_ABOVE_C,
+
+ POS_BEFORE_SUB,
+ POS_BELOW_C,
+ POS_AFTER_SUB,
+
+ POS_BEFORE_POST,
+ POS_POST_C,
+ POS_AFTER_POST,
+
+ POS_FINAL_C,
+ POS_SMVD,
+
+ POS_END
+};
+
+/* Categories used in IndicSyllabicCategory.txt from UCD. */
+enum indic_syllabic_category_t {
+ INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
+
+ INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_X,
+ INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_Repha,
+ INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
+ INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
+ INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
+ INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
+ INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
+ INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
+ INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
+ INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
+ INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
+ INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
+};
+
+/* Categories used in IndicSMatraCategory.txt from UCD */
+enum indic_matra_category_t {
+ INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END,
+
+ INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C,
+ INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C,
+ INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C,
+ INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C,
+
+ /* These should resolve to the position of the last part of the split sequence. */
+ INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+
+ INDIC_MATRA_CATEGORY_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
+ INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
+ INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
+};
+
+/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation
+ * because gcc fails to optimize the latter and fills the table in at runtime. */
+#define INDIC_COMBINE_CATEGORIES(S,M) \
+ (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || (S == INDIC_SYLLABIC_CATEGORY_VIRAMA || S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT)) + \
+ ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
+ ((M << 8) | S))
+
+HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE
+hb_indic_get_categories (hb_codepoint_t u);
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
new file mode 100644
index 0000000000..18a022bc50
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
@@ -0,0 +1,869 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ * ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # IndicSyllabicCategory-6.2.0.txt
+ * # Date: 2012-05-15, 21:12:00 GMT [KW]
+ * # IndicMatraCategory-6.2.0.txt
+ * # Date: 2012-05-15, 21:10:00 GMT [KW]
+ * # Blocks-6.2.0.txt
+ * # Date: 2012-05-14, 22:42:00 GMT [KW, LI]
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+
+
+#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 11 chars; Avagraha */
+#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 34 chars; Bindu */
+#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 123 chars; Consonant */
+#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 2 chars; Consonant_Dead */
+#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 17 chars; Consonant_Final */
+#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 1 chars; Consonant_Head_Letter */
+#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 12 chars; Consonant_Medial */
+#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 4 chars; Consonant_Placeholder */
+#define ISC_CR INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA /* 5 chars; Consonant_Repha */
+#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 10 chars; Consonant_Subjoined */
+#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
+#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 12 chars; Nukta */
+#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
+#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 1 chars; Register_Shifter */
+#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 3 chars; Tone_Letter */
+#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 16 chars; Tone_Mark */
+#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 34 chars; Virama */
+#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 25 chars; Visarga */
+#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 5 chars; Vowel */
+#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 165 chars; Vowel_Dependent */
+#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 59 chars; Vowel_Independent */
+
+#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 65 chars; Bottom */
+#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
+#define IMC_I INDIC_MATRA_CATEGORY_INVISIBLE /* 6 chars; Invisible */
+#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 30 chars; Left */
+#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 8 chars; Left_And_Right */
+#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
+#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 2 chars; Overstruck */
+#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 75 chars; Right */
+#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 83 chars; Top */
+#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 6 chars; Top_And_Bottom */
+#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
+#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 4 chars; Top_And_Left */
+#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 2 chars; Top_And_Left_And_Right */
+#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 8 chars; Top_And_Right */
+#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 5 chars; Visual_Order_Left */
+
+#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
+
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
+
+
+#define indic_offset_0x0900 0
+
+
+ /* Devanagari (0900..097F) */
+
+ /* 0900 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,x), _(A,x), _(M,R), _(M,L),
+ /* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T),
+ /* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R),
+ /* 0950 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(M,B),
+ /* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0978 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+
+ /* Bengali (0980..09FF) */
+
+ /* 0980 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
+ /* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
+ /* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L),
+ /* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
+ /* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x),
+ /* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
+ /* 09D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
+ /* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 09E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Gurmukhi (0A00..0A7F) */
+
+ /* 0A00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
+ /* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
+ /* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(x,x), _(M,R), _(M,L),
+ /* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T),
+ /* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x),
+ /* 0A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x),
+ /* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0A68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0A70 */ _(Bi,x), _(x,x), _(CP,x), _(CP,x), _(x,x), _(CM,x), _(x,x), _(x,x),
+ /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Gujarati (0A80..0AFF) */
+
+ /* 0A80 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x),
+ /* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L),
+ /* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T),
+ /* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x),
+ /* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0AD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0AE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0AF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Oriya (0B00..0B7F) */
+
+ /* 0B00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
+ /* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T),
+ /* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
+ /* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x),
+ /* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,TR),
+ /* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
+ /* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0B70 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Tamil (0B80..0BFF) */
+
+ /* 0B80 */ _(x,x), _(x,x), _(Bi,x), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x),
+ /* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x),
+ /* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x),
+ /* 0BA0 */ _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
+ /* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
+ /* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R),
+ /* 0BC0 */ _(M,T), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L),
+ /* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x),
+ /* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
+ /* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0BE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0BE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0BF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Telugu (0C00..0C7F) */
+
+ /* 0C00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
+ /* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(A,x), _(M,T), _(M,T),
+ /* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T),
+ /* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x),
+ /* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x),
+ /* 0C58 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0C68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0C78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Kannada (0C80..0CFF) */
+
+ /* 0C80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
+ /* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T),
+ /* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR),
+ /* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x),
+ /* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x),
+ /* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(x,x),
+ /* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0CF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Malayalam (0D00..0D7F) */
+
+ /* 0D00 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
+ /* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0D38 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(A,x), _(M,R), _(M,R),
+ /* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L),
+ /* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(CR,x), _(x,x),
+ /* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
+ /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0D68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0D78 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
+
+ /* Sinhala (0D80..0DFF) */
+
+ /* 0D80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x),
+ /* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DB0 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DB8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x),
+ /* 0DC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
+ /* 0DC8 */ _(x,x), _(x,x), _(V,T), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
+ /* 0DD0 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(x,x), _(M,B), _(x,x),
+ /* 0DD8 */ _(M,R), _(M,L), _(M,TL), _(M,L), _(M,LR), _(M,LR), _(M,LR), _(M,R),
+ /* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0DE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0DF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Thai (0E00..0E7F) */
+
+ /* 0E00 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0E08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0E10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0E18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0E20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0E28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
+ /* 0E30 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T),
+ /* 0E38 */ _(M,B), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0E40 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(M,R), _(x,x), _(M,T),
+ /* 0E48 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(V,T), _(x,x),
+ /* 0E50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0E58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0E60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0E68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0E70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0E78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Lao (0E80..0EFF) */
+
+ /* 0E80 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x),
+ /* 0E88 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x), _(x,x), _(x,x),
+ /* 0E90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0E98 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0EA0 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x),
+ /* 0EA8 */ _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
+ /* 0EB0 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T),
+ /* 0EB8 */ _(M,B), _(M,B), _(x,x), _(M,T), _(CM,x), _(CM,x), _(x,x), _(x,x),
+ /* 0EC0 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(x,x), _(x,x), _(x,x),
+ /* 0EC8 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(x,x), _(x,x),
+ /* 0ED0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0ED8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x),
+ /* 0EE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0EE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0EF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0EF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Tibetan (0F00..0FFF) */
+
+ /* 0F00 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F10 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F18 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F20 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F28 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F30 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0F40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0F48 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0F50 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0F58 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0F60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0F68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
+ /* 0F70 */ _(x,x), _(M,B), _(M,T), _(M,TB), _(M,B), _(M,B), _(M,TB), _(M,TB),
+ /* 0F78 */ _(M,TB), _(M,TB), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(Vs,x),
+ /* 0F80 */ _(M,T), _(M,TB), _(Bi,x), _(Bi,x), _(V,B), _(A,x), _(x,x), _(x,x),
+ /* 0F88 */_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x), _(CS,x), _(CS,x), _(CS,x),
+ /* 0F90 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
+ /* 0F98 */ _(x,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
+ /* 0FA0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
+ /* 0FA8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
+ /* 0FB0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
+ /* 0FB8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x),
+ /* 0FC0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0FC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0FD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0FD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0FE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0FE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0FF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0FF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Myanmar (1000..109F) */
+
+ /* 1000 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1008 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1010 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B),
+ /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(TM,x),
+ /* 1038 */ _(Vs,x), _(V,I), _(V,T), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(C,x),
+ /* 1040 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R),
+ /* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,x), _(CM,x),
+ /* 1060 */ _(CM,x), _(C,x), _(M,R), _(TM,x), _(TM,x), _(C,x), _(C,x), _(M,R),
+ /* 1068 */ _(M,R), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(C,x),
+ /* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x),
+ /* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1080 */ _(C,x), _(C,x), _(CM,x), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,x),
+ /* 1088 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(TM,x),
+ /* 1090 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1098 */ _(x,x), _(x,x), _(TM,x), _(TM,x), _(M,R), _(M,T), _(x,x), _(x,x),
+
+#define indic_offset_0x1700 1952
+
+
+ /* Tagalog (1700..171F) */
+
+ /* 1700 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1708 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x),
+ /* 1710 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x),
+ /* 1718 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Hanunoo (1720..173F) */
+
+ /* 1720 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1728 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1730 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x),
+ /* 1738 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Buhid (1740..175F) */
+
+ /* 1740 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1748 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1750 */ _(C,x), _(C,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1758 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Tagbanwa (1760..177F) */
+
+ /* 1760 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1768 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x),
+ /* 1770 */ _(C,x), _(x,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1778 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Khmer (1780..17FF) */
+
+ /* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1788 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1790 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1798 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 17A0 */ _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T),
+ /* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR),
+ /* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,x), _(Vs,x),
+ /* 17C8 */ _(M,R), _(RS,x), _(RS,x), _(x,x), _(CR,x), _(x,x), _(x,x), _(x,x),
+ /* 17D0 */ _(x,x), _(V,T), _(V,I), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(x,x), _(x,x), _(x,x),
+ /* 17E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 17E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 17F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 17F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x1900 2208
+
+
+ /* Limbu (1900..194F) */
+
+ /* 1900 */ _(CP,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1908 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
+ /* 1920 */ _(M,T), _(M,T), _(M,B), _(M,R), _(M,R), _(M,TR), _(M,TR), _(M,T),
+ /* 1928 */ _(M,T), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1930 */ _(CF,x), _(CF,x), _(Bi,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+ /* 1938 */ _(CF,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1948 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Tai Le (1950..197F) */
+
+ /* 1950 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1960 */ _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
+ /* 1968 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(x,x), _(x,x),
+ /* 1970 */ _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(x,x), _(x,x), _(x,x),
+ /* 1978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* New Tai Lue (1980..19DF) */
+
+ /* 1980 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1988 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 19A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 19A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 19B0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,L), _(M,L), _(M,L),
+ /* 19B8 */ _(M,R), _(M,R), _(M,L), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R),
+ /* 19C0 */ _(M,R), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+ /* 19C8 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 19D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 19D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* FILLER (19E0..19FF) */
+
+ /* 19E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 19E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 19F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 19F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Buginese (1A00..1A1F) */
+
+ /* 1A00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1A08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T),
+ /* 1A18 */ _(M,B), _(M,L), _(M,R), _(M,L), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Tai Tham (1A20..1AAF) */
+
+ /* 1A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1A38 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1A40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1A48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 1A50 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(CM,x), _(CM,x), _(CF,x),
+ /* 1A58 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x),
+ /* 1A60 */ _(V,I), _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T),
+ /* 1A68 */ _(M,T), _(M,B), _(M,B), _(M,T), _(M,B), _(M,R), _(M,L), _(M,L),
+ /* 1A70 */ _(M,L), _(M,L), _(M,L), _(M,T), _(M,T), _(TM,x), _(TM,x), _(TM,x),
+ /* 1A78 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1A80 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1A88 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1A90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1A98 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1AA0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1AA8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x1b00 2640
+
+
+ /* Balinese (1B00..1B7F) */
+
+ /* 1B00 */ _(Bi,x), _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 1B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 1B10 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1B28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1B30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,T), _(M,T),
+ /* 1B38 */ _(M,B), _(M,B), _(M,B), _(M,BR), _(M,TB),_(M,TBR), _(M,L), _(M,L),
+ /* 1B40 */ _(M,LR), _(M,LR), _(M,T), _(M,TR), _(V,R), _(C,x), _(C,x), _(C,x),
+ /* 1B48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1B60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1B70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Sundanese (1B80..1BBF) */
+
+ /* 1B80 */ _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 1B88 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1B90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1B98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1BA0 */ _(C,x), _(CS,x), _(CS,x), _(CS,x), _(M,T), _(M,B), _(M,L), _(M,R),
+ /* 1BA8 */ _(M,T), _(M,T), _(V,R), _(V,x), _(CS,x), _(CS,x), _(C,x), _(C,x),
+ /* 1BB0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1BB8 */ _(x,x), _(x,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x),
+
+ /* Batak (1BC0..1BFF) */
+
+ /* 1BC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1BC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1BD0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1BD8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1BE0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(N,x), _(M,x),
+ /* 1BE8 */ _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x),
+ /* 1BF0 */ _(CF,x), _(CF,x), _(V,R), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Lepcha (1C00..1C4F) */
+
+ /* 1C00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1C08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1C10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CS,x), _(CS,x), _(M,R), _(M,L),
+ /* 1C28 */ _(M,L), _(M,TL), _(M,R), _(M,R), _(M,B), _(CF,x), _(CF,x), _(CF,x),
+ /* 1C30 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(Bi,x), _(Bi,x), _(x,x), _(N,x),
+ /* 1C38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1C40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1C48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x),
+
+#define indic_offset_0x1cd0 2976
+
+
+ /* Vedic Extensions (1CD0..1CFF) */
+
+ /* 1CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1CE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 1CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0xa800 3024
+
+
+ /* Syloti Nagri (A800..A82F) */
+
+ /* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(V,T), _(C,x),
+ /* A808 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A810 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A818 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A820 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,B), _(M,T), _(M,R),
+ /* A828 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* FILLER (A830..A83F) */
+
+ /* A830 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A838 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Phags-pa (A840..A87F) */
+
+ /* A840 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A848 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A850 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A858 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x),
+ /* A860 */ _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(CS,x),
+ /* A868 */ _(CS,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A870 */ _(C,x), _(CS,x), _(C,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A878 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Saurashtra (A880..A8DF) */
+
+ /* A880 */ _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* A888 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* A890 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A898 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A8A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A8A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A8B0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(M,R), _(M,R), _(M,R),
+ /* A8B8 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R),
+ /* A8C0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x), _(x,x),
+ /* A8C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A8D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A8D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* FILLER (A8E0..A8FF) */
+
+ /* A8E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A8E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A8F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Kayah Li (A900..A92F) */
+
+ /* A900 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A908 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A920 */ _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
+ /* A928 */ _(Vo,x), _(Vo,x), _(Vo,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(x,x),
+
+ /* Rejang (A930..A95F) */
+
+ /* A930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A938 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A940 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,B),
+ /* A948 */ _(M,B), _(M,B), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B), _(CF,x),
+ /* A950 */ _(CF,x), _(CF,x), _(CF,x), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A958 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* FILLER (A960..A97F) */
+
+ /* A960 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A970 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Javanese (A980..A9DF) */
+
+ /* A980 */ _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* A988 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(C,x),
+ /* A990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A9A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A9A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A9B0 */ _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,R), _(M,T), _(M,T),
+ /* A9B8 */ _(M,B), _(M,B), _(M,L), _(M,L), _(M,T), _(CS,x), _(CM,x), _(CM,x),
+ /* A9C0 */ _(V,BR), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A9C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A9D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A9D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* FILLER (A9E0..A9FF) */
+
+ /* A9E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A9E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A9F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A9F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Cham (AA00..AA5F) */
+
+ /* AA00 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x),
+ /* AA08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA28 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,T), _(M,L),
+ /* AA30 */ _(M,L), _(M,T), _(M,B), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(x,x),
+ /* AA38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* AA40 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+ /* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x), _(x,x),
+ /* AA50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* AA58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Myanmar Extended-A (AA60..AA7F) */
+
+ /* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Tai Viet (AA80..AADF) */
+
+ /* AA80 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA88 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AAA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AAA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AAB0 */ _(M,T), _(M,R), _(M,T), _(M,T), _(M,B),_(M,VOL),_(M,VOL), _(M,T),
+ /* AAB8 */ _(M,T),_(M,VOL), _(M,R),_(M,VOL),_(M,VOL), _(M,R), _(M,T), _(TM,x),
+ /* AAC0 */ _(TL,x), _(TM,x), _(TL,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* AAC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* AAD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* AAD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Meetei Mayek Extensions (AAE0..AAFF) */
+
+ /* AAE0 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AAE8 */ _(C,x), _(C,x), _(C,x), _(M,L), _(M,B), _(M,T), _(M,L), _(M,R),
+ /* AAF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Vs,x), _(V,I), _(x,x),
+ /* AAF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0xabc0 3792
+
+
+ /* Meetei Mayek (ABC0..ABFF) */
+
+ /* ABC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* ABC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x),
+ /* ABD0 */ _(C,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* ABD8 */ _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+ /* ABE0 */ _(CF,x), _(CF,x), _(CF,x), _(M,R), _(M,R), _(M,T), _(M,R), _(M,R),
+ /* ABE8 */ _(M,B), _(M,R), _(M,R), _(x,x), _(TM,x), _(V,B), _(x,x), _(x,x),
+ /* ABF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* ABF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x10a00 3856
+
+
+ /* Kharoshthi (10A00..10A5F) */
+
+ /* 10A00 */ _(C,x), _(M,O), _(M,B), _(M,B), _(x,x), _(M,T), _(M,O), _(x,x),
+ /* 10A08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(M,B), _(x,x), _(Bi,x), _(Vs,x),
+ /* 10A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 10A18 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 10A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 10A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 10A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 10A38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(V,I),
+ /* 10A40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 10A48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 10A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 10A58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x11000 3952
+
+
+ /* Brahmi (11000..1107F) */
+
+ /* 11000 */ _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 11008 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 11010 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11020 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11028 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11030 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11038 */ _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B),
+ /* 11040 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x),
+ /* 11048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11050 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11058 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11060 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11068 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Kaithi (11080..110CF) */
+
+ /* 11080 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 11088 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 11090 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11098 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 110A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 110A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 110B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,R),
+ /* 110B8 */ _(M,R), _(V,B), _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 110C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 110C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x11100 4160
+
+
+ /* Chakma (11100..1114F) */
+
+ /* 11100 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x),
+ /* 11108 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11110 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11118 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11120 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T),
+ /* 11128 */ _(M,T), _(M,T), _(M,B), _(M,B), _(M,L), _(M,T), _(M,TB), _(M,TB),
+ /* 11130 */ _(M,T), _(M,B), _(M,B), _(V,I), _(V,T), _(x,x), _(x,x), _(x,x),
+ /* 11138 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11140 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 11148 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x11180 4240
+
+
+ /* Sharada (11180..111DF) */
+
+ /* 11180 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 11188 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 11190 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11198 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 111A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 111A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 111B0 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,L), _(M,R), _(M,B), _(M,B),
+ /* 111B8 */ _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,TR),
+ /* 111C0 */ _(V,R), _(A,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 111C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 111D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 111D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x11680 4336
+
+
+ /* Takri (11680..116CF) */
+
+ /* 11680 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 11688 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11690 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 11698 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 116A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 116A8 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(Vs,x), _(M,T), _(M,L), _(M,R),
+ /* 116B0 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(N,x),
+ /* 116B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 116C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 116C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_total 4416
+
+}; /* Table occupancy: 60% */
+
+INDIC_TABLE_ELEMENT_TYPE
+hb_indic_get_categories (hb_codepoint_t u)
+{
+ if (0x0900 <= u && u <= 0x10A0) return indic_table[u - 0x0900 + indic_offset_0x0900];
+ if (0x1700 <= u && u <= 0x1800) return indic_table[u - 0x1700 + indic_offset_0x1700];
+ if (0x1900 <= u && u <= 0x1AB0) return indic_table[u - 0x1900 + indic_offset_0x1900];
+ if (0x1B00 <= u && u <= 0x1C50) return indic_table[u - 0x1B00 + indic_offset_0x1b00];
+ if (0x1CD0 <= u && u <= 0x1D00) return indic_table[u - 0x1CD0 + indic_offset_0x1cd0];
+ if (0xA800 <= u && u <= 0xAB00) return indic_table[u - 0xA800 + indic_offset_0xa800];
+ if (0xABC0 <= u && u <= 0xAC00) return indic_table[u - 0xABC0 + indic_offset_0xabc0];
+ if (0x10A00 <= u && u <= 0x10A60) return indic_table[u - 0x10A00 + indic_offset_0x10a00];
+ if (0x11000 <= u && u <= 0x110D0) return indic_table[u - 0x11000 + indic_offset_0x11000];
+ if (0x11100 <= u && u <= 0x11150) return indic_table[u - 0x11100 + indic_offset_0x11100];
+ if (0x11180 <= u && u <= 0x111E0) return indic_table[u - 0x11180 + indic_offset_0x11180];
+ if (0x11680 <= u && u <= 0x116D0) return indic_table[u - 0x11680 + indic_offset_0x11680];
+ if (unlikely (u == 0x00A0)) return _(CP,x);
+ if (unlikely (u == 0x25CC)) return _(CP,x);
+ return _(x,x);
+}
+
+#undef _
+
+#undef ISC_A
+#undef ISC_Bi
+#undef ISC_C
+#undef ISC_CD
+#undef ISC_CF
+#undef ISC_CHL
+#undef ISC_CM
+#undef ISC_CP
+#undef ISC_CR
+#undef ISC_CS
+#undef ISC_ML
+#undef ISC_N
+#undef ISC_x
+#undef ISC_RS
+#undef ISC_TL
+#undef ISC_TM
+#undef ISC_V
+#undef ISC_Vs
+#undef ISC_Vo
+#undef ISC_M
+#undef ISC_VI
+
+#undef IMC_B
+#undef IMC_BR
+#undef IMC_I
+#undef IMC_L
+#undef IMC_LR
+#undef IMC_x
+#undef IMC_O
+#undef IMC_R
+#undef IMC_T
+#undef IMC_TB
+#undef IMC_TBR
+#undef IMC_TL
+#undef IMC_TLR
+#undef IMC_TR
+#undef IMC_VOL
+
+/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
new file mode 100644
index 0000000000..d3c475b6ab
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -0,0 +1,1673 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+#include "hb-ot-layout-private.hh"
+
+/* buffer var allocations */
+#define indic_category() complex_var_u8_0() /* indic_category_t */
+#define indic_position() complex_var_u8_1() /* indic_position_t */
+
+
+/*
+ * Indic shaper.
+ */
+
+
+#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7F) == (Base))
+
+#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900))
+#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980))
+#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00))
+#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80))
+#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00))
+#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80))
+#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00))
+#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80))
+#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00))
+#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80))
+#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780))
+
+
+#define MATRA_POS_LEFT(u) POS_PRE_M
+#define MATRA_POS_RIGHT(u) ( \
+ IS_DEVA(u) ? POS_AFTER_SUB : \
+ IS_BENG(u) ? POS_AFTER_POST : \
+ IS_GURU(u) ? POS_AFTER_POST : \
+ IS_GUJR(u) ? POS_AFTER_POST : \
+ IS_ORYA(u) ? POS_AFTER_POST : \
+ IS_TAML(u) ? POS_AFTER_POST : \
+ IS_TELU(u) ? (u <= 0x0C42 ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
+ IS_KNDA(u) ? (u < 0x0CC3 || u > 0xCD6 ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
+ IS_MLYM(u) ? POS_AFTER_POST : \
+ IS_SINH(u) ? POS_AFTER_SUB : \
+ IS_KHMR(u) ? POS_AFTER_POST : \
+ /*default*/ POS_AFTER_SUB \
+ )
+#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \
+ IS_DEVA(u) ? POS_AFTER_SUB : \
+ IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \
+ IS_GUJR(u) ? POS_AFTER_SUB : \
+ IS_ORYA(u) ? POS_AFTER_MAIN : \
+ IS_TAML(u) ? POS_AFTER_SUB : \
+ IS_TELU(u) ? POS_BEFORE_SUB : \
+ IS_KNDA(u) ? POS_BEFORE_SUB : \
+ IS_SINH(u) ? POS_AFTER_SUB : \
+ IS_KHMR(u) ? POS_AFTER_POST : \
+ /*default*/ POS_AFTER_SUB \
+ )
+#define MATRA_POS_BOTTOM(u) ( \
+ IS_DEVA(u) ? POS_AFTER_SUB : \
+ IS_BENG(u) ? POS_AFTER_SUB : \
+ IS_GURU(u) ? POS_AFTER_POST : \
+ IS_GUJR(u) ? POS_AFTER_POST : \
+ IS_ORYA(u) ? POS_AFTER_SUB : \
+ IS_TAML(u) ? POS_AFTER_POST : \
+ IS_TELU(u) ? POS_BEFORE_SUB : \
+ IS_KNDA(u) ? POS_BEFORE_SUB : \
+ IS_MLYM(u) ? POS_AFTER_POST : \
+ IS_SINH(u) ? POS_AFTER_SUB : \
+ IS_KHMR(u) ? POS_AFTER_POST : \
+ /*default*/ POS_AFTER_SUB \
+ )
+
+static inline indic_position_t
+matra_position (hb_codepoint_t u, indic_position_t side)
+{
+ switch ((int) side)
+ {
+ case POS_PRE_C: return MATRA_POS_LEFT (u);
+ case POS_POST_C: return MATRA_POS_RIGHT (u);
+ case POS_ABOVE_C: return MATRA_POS_TOP (u);
+ case POS_BELOW_C: return MATRA_POS_BOTTOM (u);
+ };
+ return side;
+}
+
+/* XXX
+ * This is a hack for now. We should move this data into the main Indic table.
+ * Or completely remove it and just check in the tables.
+ */
+static const hb_codepoint_t ra_chars[] = {
+ 0x0930, /* Devanagari */
+ 0x09B0, /* Bengali */
+ 0x09F0, /* Bengali */
+ 0x0A30, /* Gurmukhi */ /* No Reph */
+ 0x0AB0, /* Gujarati */
+ 0x0B30, /* Oriya */
+ 0x0BB0, /* Tamil */ /* No Reph */
+ 0x0C30, /* Telugu */ /* Reph formed only with ZWJ */
+ 0x0CB0, /* Kannada */
+ 0x0D30, /* Malayalam */ /* No Reph, Logical Repha */
+
+ 0x0DBB, /* Sinhala */ /* Reph formed only with ZWJ */
+
+ 0x179A, /* Khmer */ /* No Reph, Visual Repha */
+};
+
+static inline indic_position_t
+consonant_position (hb_codepoint_t u)
+{
+ if ((u & ~0x007F) == 0x1780)
+ return POS_BELOW_C; /* In Khmer coeng model, post and below forms should not be reordered. */
+ return POS_BASE_C; /* Will recategorize later based on font lookups. */
+}
+
+static inline bool
+is_ra (hb_codepoint_t u)
+{
+ for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++)
+ if (u == ra_chars[i])
+ return true;
+ return false;
+}
+
+static inline bool
+is_one_of (const hb_glyph_info_t &info, unsigned int flags)
+{
+ /* If it ligated, all bets are off. */
+ if (is_a_ligature (info)) return false;
+ return !!(FLAG (info.indic_category()) & flags);
+}
+
+#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
+static inline bool
+is_joiner (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, JOINER_FLAGS);
+}
+
+/* Note:
+ *
+ * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
+ * cannot happen in a consonant syllable. The plus side however is, we can call the
+ * consonant syllable logic from the vowel syllable function and get it all right! */
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
+static inline bool
+is_consonant (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, CONSONANT_FLAGS);
+}
+
+#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
+static inline bool
+is_halant_or_coeng (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, HALANT_OR_COENG_FLAGS);
+}
+
+static inline void
+set_indic_properties (hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+ indic_category_t cat = (indic_category_t) (type & 0x7F);
+ indic_position_t pos = (indic_position_t) (type >> 8);
+
+
+ /*
+ * Re-assign category
+ */
+
+
+ /* The spec says U+0952 is OT_A. However, testing shows that Uniscribe
+ * treats U+0951..U+0952 all as OT_VD.
+ * TESTS:
+ * U+092E,U+0947,U+0952
+ * U+092E,U+0952,U+0947
+ * U+092E,U+0947,U+0951
+ * U+092E,U+0951,U+0947
+ * */
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0951, 0x0954)))
+ cat = OT_VD;
+
+ if (unlikely (u == 0x17D1))
+ cat = OT_X;
+ if (cat == OT_X &&
+ unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CB, 0x17D3))) /* Khmer Various signs */
+ {
+ /* These are like Top Matras. */
+ cat = OT_M;
+ pos = POS_ABOVE_C;
+ }
+ if (u == 0x17C6) /* Khmer Bindu doesn't like to be repositioned. */
+ cat = OT_N;
+
+ if (unlikely (u == 0x17D2)) cat = OT_Coeng; /* Khmer coeng */
+ else if (unlikely (u == 0x200C)) cat = OT_ZWNJ;
+ else if (unlikely (u == 0x200D)) cat = OT_ZWJ;
+ else if (unlikely (u == 0x25CC)) cat = OT_DOTTEDCIRCLE;
+ else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK. More like consonant medial. like 0A75. */
+
+ if (cat == OT_Repha) {
+ /* There are two kinds of characters marked as Repha:
+ * - The ones that are GenCat=Mn are already positioned visually, ie. after base. (eg. Khmer)
+ * - The ones that are GenCat=Lo is encoded logically, ie. beginning of syllable. (eg. Malayalam)
+ *
+ * We recategorize the first kind to look like a Nukta and attached to the base directly.
+ */
+ if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ cat = OT_N;
+ }
+
+
+
+ /*
+ * Re-assign position.
+ */
+
+ if ((FLAG (cat) & CONSONANT_FLAGS))
+ {
+ pos = consonant_position (u);
+ if (is_ra (u))
+ cat = OT_Ra;
+ }
+ else if (cat == OT_M)
+ {
+ pos = matra_position (u, pos);
+ }
+ else if (cat == OT_SM || cat == OT_VD)
+ {
+ pos = POS_SMVD;
+ }
+
+ if (unlikely (u == 0x0B01)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */
+
+
+
+ info.indic_category() = cat;
+ info.indic_position() = pos;
+}
+
+/*
+ * Things above this line should ideally be moved to the Indic table itself.
+ */
+
+
+/*
+ * Indic configurations. Note that we do not want to keep every single script-specific
+ * behavior in these tables necessarily. This should mainly be used for per-script
+ * properties that are cheaper keeping here, than in the code. Ie. if, say, one and
+ * only one script has an exception, that one script can be if'ed directly in the code,
+ * instead of adding a new flag in these structs.
+ */
+
+enum base_position_t {
+ BASE_POS_FIRST,
+ BASE_POS_LAST
+};
+enum reph_position_t {
+ REPH_POS_DEFAULT = POS_BEFORE_POST,
+
+ REPH_POS_AFTER_MAIN = POS_AFTER_MAIN,
+ REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
+ REPH_POS_AFTER_SUB = POS_AFTER_SUB,
+ REPH_POS_BEFORE_POST = POS_BEFORE_POST,
+ REPH_POS_AFTER_POST = POS_AFTER_POST
+};
+enum reph_mode_t {
+ REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */
+ REPH_MODE_EXPLICIT, /* Reph formed out of initial Ra,H,ZWJ sequence. */
+ REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
+ REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */
+};
+struct indic_config_t
+{
+ hb_script_t script;
+ bool has_old_spec;
+ hb_codepoint_t virama;
+ base_position_t base_pos;
+ reph_position_t reph_pos;
+ reph_mode_t reph_mode;
+};
+
+static const indic_config_t indic_configs[] =
+{
+ /* Default. Should be first. */
+ {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT},
+ {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA},
+ {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT},
+ {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT, REPH_MODE_VIS_REPHA},
+ {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT},
+};
+
+
+
+/*
+ * Indic shaper.
+ */
+
+struct feature_list_t {
+ hb_tag_t tag;
+ hb_ot_map_feature_flags_t flags;
+};
+
+static const feature_list_t
+indic_features[] =
+{
+ /*
+ * Basic features.
+ * These features are applied in order, one at a time, after initial_reordering.
+ */
+ {HB_TAG('n','u','k','t'), F_GLOBAL},
+ {HB_TAG('a','k','h','n'), F_GLOBAL},
+ {HB_TAG('r','p','h','f'), F_NONE},
+ {HB_TAG('r','k','r','f'), F_GLOBAL},
+ {HB_TAG('p','r','e','f'), F_NONE},
+ {HB_TAG('b','l','w','f'), F_NONE},
+ {HB_TAG('h','a','l','f'), F_NONE},
+ {HB_TAG('a','b','v','f'), F_NONE},
+ {HB_TAG('p','s','t','f'), F_NONE},
+ {HB_TAG('c','f','a','r'), F_NONE},
+ {HB_TAG('v','a','t','u'), F_GLOBAL},
+ {HB_TAG('c','j','c','t'), F_GLOBAL},
+ /*
+ * Other features.
+ * These features are applied all at once, after final_reordering.
+ */
+ {HB_TAG('i','n','i','t'), F_NONE},
+ {HB_TAG('p','r','e','s'), F_GLOBAL},
+ {HB_TAG('a','b','v','s'), F_GLOBAL},
+ {HB_TAG('b','l','w','s'), F_GLOBAL},
+ {HB_TAG('p','s','t','s'), F_GLOBAL},
+ {HB_TAG('h','a','l','n'), F_GLOBAL},
+ /* Positioning features, though we don't care about the types. */
+ {HB_TAG('d','i','s','t'), F_GLOBAL},
+ {HB_TAG('a','b','v','m'), F_GLOBAL},
+ {HB_TAG('b','l','w','m'), F_GLOBAL},
+};
+
+/*
+ * Must be in the same order as the indic_features array.
+ */
+enum {
+ _NUKT,
+ _AKHN,
+ RPHF,
+ _RKRF,
+ PREF,
+ BLWF,
+ HALF,
+ ABVF,
+ PSTF,
+ CFAR,
+ _VATU,
+ _CJCT,
+
+ INIT,
+ _PRES,
+ _ABVS,
+ _BLWS,
+ _PSTS,
+ _HALN,
+ _DIST,
+ _ABVM,
+ _BLWM,
+
+ INDIC_NUM_FEATURES,
+ INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
+collect_features_indic (hb_ot_shape_planner_t *plan)
+{
+ hb_ot_map_builder_t *map = &plan->map;
+
+ /* Do this before any lookups have been applied. */
+ map->add_gsub_pause (setup_syllables);
+
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+ /* The Indic specs do not require ccmp, but we apply it here since if
+ * there is a use of it, it's typically at the beginning. */
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+
+
+ unsigned int i = 0;
+ map->add_gsub_pause (initial_reordering);
+ for (; i < INDIC_BASIC_FEATURES; i++) {
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
+ map->add_gsub_pause (NULL);
+ }
+ map->add_gsub_pause (final_reordering);
+ for (; i < INDIC_NUM_FEATURES; i++) {
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
+ }
+}
+
+static void
+override_features_indic (hb_ot_shape_planner_t *plan)
+{
+ /* Uniscribe does not apply 'kern'. */
+ if (hb_options ().uniscribe_bug_compatible)
+ plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+}
+
+
+struct would_substitute_feature_t
+{
+ inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag)
+ {
+ map->get_stage_lookups (0/*GSUB*/,
+ map->get_feature_stage (0/*GSUB*/, feature_tag),
+ &lookups, &count);
+ }
+
+ inline bool would_substitute (const hb_codepoint_t *glyphs,
+ unsigned int glyphs_count,
+ bool zero_context,
+ hb_face_t *face) const
+ {
+ for (unsigned int i = 0; i < count; i++)
+ if (hb_ot_layout_lookup_would_substitute_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context))
+ return true;
+ return false;
+ }
+
+ private:
+ const hb_ot_map_t::lookup_map_t *lookups;
+ unsigned int count;
+};
+
+struct indic_shape_plan_t
+{
+ ASSERT_POD ();
+
+ inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
+ {
+ hb_codepoint_t glyph = virama_glyph;
+ if (unlikely (virama_glyph == (hb_codepoint_t) -1))
+ {
+ if (!config->virama || !font->get_glyph (config->virama, 0, &glyph))
+ glyph = 0;
+ /* Technically speaking, the spec says we should apply 'locl' to virama too.
+ * Maybe one day... */
+
+ /* Our get_glyph() function needs a font, so we can't get the virama glyph
+ * during shape planning... Instead, overwrite it here. It's safe. Don't worry! */
+ (const_cast<indic_shape_plan_t *> (this))->virama_glyph = glyph;
+ }
+
+ *pglyph = glyph;
+ return glyph != 0;
+ }
+
+ const indic_config_t *config;
+
+ bool is_old_spec;
+ hb_codepoint_t virama_glyph;
+
+ would_substitute_feature_t rphf;
+ would_substitute_feature_t pref;
+ would_substitute_feature_t blwf;
+ would_substitute_feature_t pstf;
+
+ hb_mask_t mask_array[INDIC_NUM_FEATURES];
+};
+
+static void *
+data_create_indic (const hb_ot_shape_plan_t *plan)
+{
+ indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
+ if (unlikely (!indic_plan))
+ return NULL;
+
+ indic_plan->config = &indic_configs[0];
+ for (unsigned int i = 1; i < ARRAY_LENGTH (indic_configs); i++)
+ if (plan->props.script == indic_configs[i].script) {
+ indic_plan->config = &indic_configs[i];
+ break;
+ }
+
+ indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FF) != '2');
+ indic_plan->virama_glyph = (hb_codepoint_t) -1;
+
+ indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'));
+ indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'));
+ indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'));
+ indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'));
+
+ for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
+ indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
+ 0 : plan->map.get_1_mask (indic_features[i].tag);
+
+ return indic_plan;
+}
+
+static void
+data_destroy_indic (void *data)
+{
+ free (data);
+}
+
+static indic_position_t
+consonant_position_from_face (const indic_shape_plan_t *indic_plan,
+ const hb_codepoint_t glyphs[2],
+ hb_face_t *face)
+{
+ /* For old-spec, the order of glyphs is Consonant,Virama,
+ * whereas for new-spec, it's Virama,Consonant. However,
+ * some broken fonts (like Free Sans) simply copied lookups
+ * from old-spec to new-spec without modification.
+ * And oddly enough, Uniscribe seems to respect those lookups.
+ * Eg. in the sequence U+0924,U+094D,U+0930, Uniscribe finds
+ * base at 0. The font however, only has lookups matching
+ * 930,94D in 'blwf', not the expected 94D,930 (with new-spec
+ * table). As such, we simply match both sequences. Seems
+ * to work. */
+ bool zero_context = indic_plan->is_old_spec ? false : true;
+ hb_codepoint_t glyphs_r[2] = {glyphs[1], glyphs[0]};
+ if (indic_plan->pref.would_substitute (glyphs , 2, zero_context, face) ||
+ indic_plan->pref.would_substitute (glyphs_r, 2, zero_context, face))
+ return POS_POST_C;
+ if (indic_plan->blwf.would_substitute (glyphs , 2, zero_context, face) ||
+ indic_plan->blwf.would_substitute (glyphs_r, 2, zero_context, face))
+ return POS_BELOW_C;
+ if (indic_plan->pstf.would_substitute (glyphs , 2, zero_context, face) ||
+ indic_plan->pstf.would_substitute (glyphs_r, 2, zero_context, face))
+ return POS_POST_C;
+ return POS_BASE_C;
+}
+
+
+enum syllable_type_t {
+ consonant_syllable,
+ vowel_syllable,
+ standalone_cluster,
+ broken_cluster,
+ non_indic_cluster,
+};
+
+#include "hb-ot-shape-complex-indic-machine.hh"
+
+
+static void
+setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
+ HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
+
+ /* We cannot setup masks here. We save information about characters
+ * and setup masks later on in a pause-callback. */
+
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ set_indic_properties (buffer->info[i]);
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ find_syllables (buffer);
+}
+
+static int
+compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+ int a = pa->indic_position();
+ int b = pb->indic_position();
+
+ return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+
+static void
+update_consonant_positions (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+
+ hb_codepoint_t glyphs[2];
+ if (indic_plan->get_virama_glyph (font, &glyphs[0]))
+ {
+ hb_face_t *face = font->face;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if (buffer->info[i].indic_position() == POS_BASE_C) {
+ glyphs[1] = buffer->info[i].codepoint;
+ buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, glyphs, face);
+ }
+ }
+}
+
+
+/* Rules from:
+ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
+
+static void
+initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+ hb_glyph_info_t *info = buffer->info;
+
+
+ /* 1. Find base consonant:
+ *
+ * The shaping engine finds the base consonant of the syllable, using the
+ * following algorithm: starting from the end of the syllable, move backwards
+ * until a consonant is found that does not have a below-base or post-base
+ * form (post-base forms have to follow below-base forms), or that is not a
+ * pre-base reordering Ra, or arrive at the first consonant. The consonant
+ * stopped at will be the base.
+ *
+ * o If the syllable starts with Ra + Halant (in a script that has Reph)
+ * and has more than one consonant, Ra is excluded from candidates for
+ * base consonants.
+ */
+
+ unsigned int base = end;
+ bool has_reph = false;
+
+ {
+ /* -> If the syllable starts with Ra + Halant (in a script that has Reph)
+ * and has more than one consonant, Ra is excluded from candidates for
+ * base consonants. */
+ unsigned int limit = start;
+ if (indic_plan->mask_array[RPHF] &&
+ start + 3 <= end &&
+ (
+ (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
+ (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ)
+ ))
+ {
+ /* See if it matches the 'rphf' feature. */
+ hb_codepoint_t glyphs[2] = {info[start].codepoint, info[start + 1].codepoint};
+ if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
+ {
+ limit += 2;
+ while (limit < end && is_joiner (info[limit]))
+ limit++;
+ base = start;
+ has_reph = true;
+ }
+ } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == OT_Repha)
+ {
+ limit += 1;
+ while (limit < end && is_joiner (info[limit]))
+ limit++;
+ base = start;
+ has_reph = true;
+ }
+
+ switch (indic_plan->config->base_pos)
+ {
+ default:
+ assert (false);
+ /* fallthrough */
+
+ case BASE_POS_LAST:
+ {
+ /* -> starting from the end of the syllable, move backwards */
+ unsigned int i = end;
+ bool seen_below = false;
+ do {
+ i--;
+ /* -> until a consonant is found */
+ if (is_consonant (info[i]))
+ {
+ /* -> that does not have a below-base or post-base form
+ * (post-base forms have to follow below-base forms), */
+ if (info[i].indic_position() != POS_BELOW_C &&
+ (info[i].indic_position() != POS_POST_C || seen_below))
+ {
+ base = i;
+ break;
+ }
+ if (info[i].indic_position() == POS_BELOW_C)
+ seen_below = true;
+
+ /* -> or that is not a pre-base reordering Ra,
+ *
+ * IMPLEMENTATION NOTES:
+ *
+ * Our pre-base reordering Ra's are marked POS_POST_C, so will be skipped
+ * by the logic above already.
+ */
+
+ /* -> or arrive at the first consonant. The consonant stopped at will
+ * be the base. */
+ base = i;
+ }
+ else
+ {
+ /* A ZWJ after a Halant stops the base search, and requests an explicit
+ * half form.
+ * A ZWJ before a Halant, requests a subjoined form instead, and hence
+ * search continues. This is particularly important for Bengali
+ * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
+ if (start < i &&
+ info[i].indic_category() == OT_ZWJ &&
+ info[i - 1].indic_category() == OT_H)
+ break;
+ }
+ } while (i > limit);
+ }
+ break;
+
+ case BASE_POS_FIRST:
+ {
+ /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */
+
+ if (!has_reph)
+ base = limit;
+
+ /* Find the last base consonant that is not blocked by ZWJ. If there is
+ * a ZWJ right before a base consonant, that would request a subjoined form. */
+ for (unsigned int i = limit; i < end; i++)
+ if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ {
+ if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
+ break;
+ else
+ base = i;
+ }
+
+ /* Mark all subsequent consonants as below. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ info[i].indic_position() = POS_BELOW_C;
+ }
+ break;
+ }
+
+ /* -> If the syllable starts with Ra + Halant (in a script that has Reph)
+ * and has more than one consonant, Ra is excluded from candidates for
+ * base consonants.
+ *
+ * Only do this for unforced Reph. (ie. not for Ra,H,ZWJ. */
+ if (has_reph && base == start && limit - base <= 2) {
+ /* Have no other consonant, so Reph is not formed and Ra becomes base. */
+ has_reph = false;
+ }
+ }
+
+
+ /* 2. Decompose and reorder Matras:
+ *
+ * Each matra and any syllable modifier sign in the cluster are moved to the
+ * appropriate position relative to the consonant(s) in the cluster. The
+ * shaping engine decomposes two- or three-part matras into their constituent
+ * parts before any repositioning. Matra characters are classified by which
+ * consonant in a conjunct they have affinity for and are reordered to the
+ * following positions:
+ *
+ * o Before first half form in the syllable
+ * o After subjoined consonants
+ * o After post-form consonant
+ * o After main consonant (for above marks)
+ *
+ * IMPLEMENTATION NOTES:
+ *
+ * The normalize() routine has already decomposed matras for us, so we don't
+ * need to worry about that.
+ */
+
+
+ /* 3. Reorder marks to canonical order:
+ *
+ * Adjacent nukta and halant or nukta and vedic sign are always repositioned
+ * if necessary, so that the nukta is first.
+ *
+ * IMPLEMENTATION NOTES:
+ *
+ * We don't need to do this: the normalize() routine already did this for us.
+ */
+
+
+ /* Reorder characters */
+
+ for (unsigned int i = start; i < base; i++)
+ info[i].indic_position() = MIN (POS_PRE_C, (indic_position_t) info[i].indic_position());
+
+ if (base < end)
+ info[base].indic_position() = POS_BASE_C;
+
+ /* Mark final consonants. A final consonant is one appearing after a matra,
+ * like in Khmer. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (info[i].indic_category() == OT_M) {
+ for (unsigned int j = i + 1; j < end; j++)
+ if (is_consonant (info[j])) {
+ info[j].indic_position() = POS_FINAL_C;
+ break;
+ }
+ break;
+ }
+
+ /* Handle beginning Ra */
+ if (has_reph)
+ info[start].indic_position() = POS_RA_TO_BECOME_REPH;
+
+ /* For old-style Indic script tags, move the first post-base Halant after
+ * last consonant. Only do this if there is *not* a Halant after last
+ * consonant. Otherwise it becomes messy. */
+ if (indic_plan->is_old_spec) {
+ for (unsigned int i = base + 1; i < end; i++)
+ if (info[i].indic_category() == OT_H) {
+ unsigned int j;
+ for (j = end - 1; j > i; j--)
+ if (is_consonant (info[j]) || info[j].indic_category() == OT_H)
+ break;
+ if (info[j].indic_category() != OT_H && j > i) {
+ /* Move Halant to after last consonant. */
+ hb_glyph_info_t t = info[i];
+ memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
+ info[j] = t;
+ }
+ break;
+ }
+ }
+
+ /* Attach misc marks to previous char to move with them. */
+ {
+ indic_position_t last_pos = POS_START;
+ for (unsigned int i = start; i < end; i++)
+ {
+ if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | HALANT_OR_COENG_FLAGS)))
+ {
+ info[i].indic_position() = last_pos;
+ if (unlikely (info[i].indic_category() == OT_H &&
+ info[i].indic_position() == POS_PRE_M))
+ {
+ /*
+ * Uniscribe doesn't move the Halant with Left Matra.
+ * TEST: U+092B,U+093F,U+094DE
+ * We follow. This is important for the Sinhala
+ * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
+ * where U+0DD9 is a left matra and U+0DCA is the virama.
+ * We don't want to move the virama with the left matra.
+ * TEST: U+0D9A,U+0DDA
+ */
+ for (unsigned int j = i; j > start; j--)
+ if (info[j - 1].indic_position() != POS_PRE_M) {
+ info[i].indic_position() = info[j - 1].indic_position();
+ break;
+ }
+ }
+ } else if (info[i].indic_position() != POS_SMVD) {
+ last_pos = (indic_position_t) info[i].indic_position();
+ }
+ }
+ }
+ /* Re-attach ZWJ, ZWNJ, and halant to next char, for after-base consonants. */
+ {
+ unsigned int last_halant = end;
+ for (unsigned int i = base + 1; i < end; i++)
+ if (is_halant_or_coeng (info[i]))
+ last_halant = i;
+ else if (is_consonant (info[i])) {
+ for (unsigned int j = last_halant; j < i; j++)
+ if (info[j].indic_position() != POS_SMVD)
+ info[j].indic_position() = info[i].indic_position();
+ }
+ }
+
+ {
+ /* Things are out-of-control for post base positions, they may shuffle
+ * around like crazy, so merge clusters. For pre-base stuff, we handle
+ * cluster issues in final reordering. */
+ buffer->merge_clusters (base, end);
+ /* Sit tight, rock 'n roll! */
+ hb_bubble_sort (info + start, end - start, compare_indic_order);
+ /* Find base again */
+ base = end;
+ for (unsigned int i = start; i < end; i++)
+ if (info[i].indic_position() == POS_BASE_C) {
+ base = i;
+ break;
+ }
+ }
+
+ /* Setup masks now */
+
+ {
+ hb_mask_t mask;
+
+ /* Reph */
+ for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
+ info[i].mask |= indic_plan->mask_array[RPHF];
+
+ /* Pre-base */
+ mask = indic_plan->mask_array[HALF];
+ for (unsigned int i = start; i < base; i++)
+ info[i].mask |= mask;
+ /* Base */
+ mask = 0;
+ if (base < end)
+ info[base].mask |= mask;
+ /* Post-base */
+ mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF];
+ for (unsigned int i = base + 1; i < end; i++)
+ info[i].mask |= mask;
+ }
+
+ if (indic_plan->is_old_spec &&
+ buffer->props.script == HB_SCRIPT_DEVANAGARI)
+ {
+ /* Old-spec eye-lash Ra needs special handling. From the
+ * spec:
+ *
+ * "The feature 'below-base form' is applied to consonants
+ * having below-base forms and following the base consonant.
+ * The exception is vattu, which may appear below half forms
+ * as well as below the base glyph. The feature 'below-base
+ * form' will be applied to all such occurrences of Ra as well."
+ *
+ * Test case: U+0924,U+094D,U+0930,U+094d,U+0915
+ * with Sanskrit 2003 font.
+ *
+ * However, note that Ra,Halant,ZWJ is the correct way to
+ * request eyelash form of Ra, so we wouldbn't inhibit it
+ * in that sequence.
+ *
+ * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915
+ */
+ for (unsigned int i = start; i + 1 < base; i++)
+ if (info[i ].indic_category() == OT_Ra &&
+ info[i+1].indic_category() == OT_H &&
+ (i + 2 == base ||
+ info[i+2].indic_category() != OT_ZWJ))
+ {
+ info[i ].mask |= indic_plan->mask_array[BLWF];
+ info[i+1].mask |= indic_plan->mask_array[BLWF];
+ }
+ }
+
+ if (indic_plan->mask_array[PREF] && base + 2 < end)
+ {
+ /* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
+ for (unsigned int i = base + 1; i + 1 < end; i++) {
+ hb_codepoint_t glyphs[2] = {info[i].codepoint, info[i + 1].codepoint};
+ if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
+ {
+ info[i++].mask |= indic_plan->mask_array[PREF];
+ info[i++].mask |= indic_plan->mask_array[PREF];
+
+ /* Mark the subsequent stuff with 'cfar'. Used in Khmer.
+ * Read the feature spec.
+ * This allows distinguishing the following cases with MS Khmer fonts:
+ * U+1784,U+17D2,U+179A,U+17D2,U+1782
+ * U+1784,U+17D2,U+1782,U+17D2,U+179A
+ */
+ for (; i < end; i++)
+ info[i].mask |= indic_plan->mask_array[CFAR];
+
+ break;
+ }
+ }
+ }
+
+ /* Apply ZWJ/ZWNJ effects */
+ for (unsigned int i = start + 1; i < end; i++)
+ if (is_joiner (info[i])) {
+ bool non_joiner = info[i].indic_category() == OT_ZWNJ;
+ unsigned int j = i;
+
+ do {
+ j--;
+
+ /* ZWJ/ZWNJ should disable CJCT. They do that by simply
+ * being there, since we don't skip them for the CJCT
+ * feature (ie. F_MANUAL_ZWJ) */
+
+ /* A ZWNJ disables HALF. */
+ if (non_joiner)
+ info[j].mask &= ~indic_plan->mask_array[HALF];
+
+ } while (j > start && !is_consonant (info[j]));
+ }
+}
+
+
+static void
+initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ /* We made the vowels look like consonants. So let's call the consonant logic! */
+ initial_reordering_consonant_syllable (plan, face, buffer, start, end);
+}
+
+static void
+initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ /* We treat NBSP/dotted-circle as if they are consonants, so we should just chain.
+ * Only if not in compatibility mode that is... */
+
+ if (hb_options ().uniscribe_bug_compatible)
+ {
+ /* For dotted-circle, this is what Uniscribe does:
+ * If dotted-circle is the last glyph, it just does nothing.
+ * Ie. It doesn't form Reph. */
+ if (buffer->info[end - 1].indic_category() == OT_DOTTEDCIRCLE)
+ return;
+ }
+
+ initial_reordering_consonant_syllable (plan, face, buffer, start, end);
+}
+
+static void
+initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ /* We already inserted dotted-circles, so just call the standalone_cluster. */
+ initial_reordering_standalone_cluster (plan, face, buffer, start, end);
+}
+
+static void
+initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ hb_buffer_t *buffer HB_UNUSED,
+ unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
+{
+ /* Nothing to do right now. If we ever switch to using the output
+ * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+
+static void
+initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+ switch (syllable_type) {
+ case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
+ case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return;
+ case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return;
+ case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
+ case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return;
+ }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ /* Note: This loop is extra overhead, but should not be measurable. */
+ bool has_broken_syllables = false;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
+ has_broken_syllables = true;
+ break;
+ }
+ if (likely (!has_broken_syllables))
+ return;
+
+
+ hb_codepoint_t dottedcircle_glyph;
+ if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
+ return;
+
+ hb_glyph_info_t dottedcircle = {0};
+ dottedcircle.codepoint = 0x25CC;
+ set_indic_properties (dottedcircle);
+ dottedcircle.codepoint = dottedcircle_glyph;
+
+ buffer->clear_output ();
+
+ buffer->idx = 0;
+ unsigned int last_syllable = 0;
+ while (buffer->idx < buffer->len)
+ {
+ unsigned int syllable = buffer->cur().syllable();
+ syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+ if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+ {
+ last_syllable = syllable;
+
+ hb_glyph_info_t info = dottedcircle;
+ info.cluster = buffer->cur().cluster;
+ info.mask = buffer->cur().mask;
+ info.syllable() = buffer->cur().syllable();
+
+ /* Insert dottedcircle after possible Repha. */
+ while (buffer->idx < buffer->len &&
+ last_syllable == buffer->cur().syllable() &&
+ buffer->cur().indic_category() == OT_Repha)
+ buffer->next_glyph ();
+
+ buffer->output_info (info);
+ }
+ else
+ buffer->next_glyph ();
+ }
+
+ buffer->swap_buffers ();
+}
+
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ update_consonant_positions (plan, font, buffer);
+ insert_dotted_circles (plan, font, buffer);
+
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+ unsigned int last = 0;
+ unsigned int last_syllable = info[0].syllable();
+ for (unsigned int i = 1; i < count; i++)
+ if (last_syllable != info[i].syllable()) {
+ initial_reordering_syllable (plan, font->face, buffer, last, i);
+ last = i;
+ last_syllable = info[last].syllable();
+ }
+ initial_reordering_syllable (plan, font->face, buffer, last, count);
+}
+
+static void
+final_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+ hb_glyph_info_t *info = buffer->info;
+
+ /* 4. Final reordering:
+ *
+ * After the localized forms and basic shaping forms GSUB features have been
+ * applied (see below), the shaping engine performs some final glyph
+ * reordering before applying all the remaining font features to the entire
+ * cluster.
+ */
+
+ /* Find base again */
+ unsigned int base;
+ for (base = start; base < end; base++)
+ if (info[base].indic_position() >= POS_BASE_C) {
+ if (start < base && info[base].indic_position() > POS_BASE_C)
+ base--;
+ break;
+ }
+ if (base == end && start < base &&
+ info[base - 1].indic_category() != OT_ZWJ)
+ base--;
+ while (start < base &&
+ (info[base].indic_category() == OT_H ||
+ info[base].indic_category() == OT_N))
+ base--;
+
+
+ /* o Reorder matras:
+ *
+ * If a pre-base matra character had been reordered before applying basic
+ * features, the glyph can be moved closer to the main consonant based on
+ * whether half-forms had been formed. Actual position for the matra is
+ * defined as “after last standalone halant glyph, after initial matra
+ * position and before the main consonant”. If ZWJ or ZWNJ follow this
+ * halant, position is moved after it.
+ */
+
+ if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */
+ {
+ /* If we lost track of base, alas, position before last thingy. */
+ unsigned int new_pos = base == end ? base - 2 : base - 1;
+
+ /* Malayalam / Tamil do not have "half" forms or explicit virama forms.
+ * The glyphs formed by 'half' are Chillus or ligated explicit viramas.
+ * We want to position matra after them.
+ */
+ if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
+ {
+ while (new_pos > start &&
+ !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H) | FLAG (OT_Coeng)))))
+ new_pos--;
+
+ /* If we found no Halant we are done.
+ * Otherwise only proceed if the Halant does
+ * not belong to the Matra itself! */
+ if (is_halant_or_coeng (info[new_pos]) &&
+ info[new_pos].indic_position() != POS_PRE_M)
+ {
+ /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
+ if (new_pos + 1 < end && is_joiner (info[new_pos + 1]))
+ new_pos++;
+ }
+ else
+ new_pos = start; /* No move. */
+ }
+
+ if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M)
+ {
+ /* Now go see if there's actually any matras... */
+ for (unsigned int i = new_pos; i > start; i--)
+ if (info[i - 1].indic_position () == POS_PRE_M)
+ {
+ unsigned int old_pos = i - 1;
+ hb_glyph_info_t tmp = info[old_pos];
+ memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0]));
+ info[new_pos] = tmp;
+ if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */
+ base--;
+ new_pos--;
+ }
+ buffer->merge_clusters (new_pos, MIN (end, base + 1));
+ } else {
+ for (unsigned int i = start; i < base; i++)
+ if (info[i].indic_position () == POS_PRE_M) {
+ buffer->merge_clusters (i, MIN (end, base + 1));
+ break;
+ }
+ }
+ }
+
+
+ /* o Reorder reph:
+ *
+ * Reph’s original position is always at the beginning of the syllable,
+ * (i.e. it is not reordered at the character reordering stage). However,
+ * it will be reordered according to the basic-forms shaping results.
+ * Possible positions for reph, depending on the script, are; after main,
+ * before post-base consonant forms, and after post-base consonant forms.
+ */
+
+ /* If there's anything after the Ra that has the REPH pos, it ought to be halant.
+ * Which means that the font has failed to ligate the Reph. In which case, we
+ * shouldn't move. */
+ if (start + 1 < end &&
+ info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
+ info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
+ {
+ unsigned int new_reph_pos;
+ reph_position_t reph_pos = indic_plan->config->reph_pos;
+
+ /* XXX Figure out old behavior too */
+
+ /* 1. If reph should be positioned after post-base consonant forms,
+ * proceed to step 5.
+ */
+ if (reph_pos == REPH_POS_AFTER_POST)
+ {
+ goto reph_step_5;
+ }
+
+ /* 2. If the reph repositioning class is not after post-base: target
+ * position is after the first explicit halant glyph between the
+ * first post-reph consonant and last main consonant. If ZWJ or ZWNJ
+ * are following this halant, position is moved after it. If such
+ * position is found, this is the target position. Otherwise,
+ * proceed to the next step.
+ *
+ * Note: in old-implementation fonts, where classifications were
+ * fixed in shaping engine, there was no case where reph position
+ * will be found on this step.
+ */
+ {
+ new_reph_pos = start + 1;
+ while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
+ new_reph_pos++;
+
+ if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
+ {
+ /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
+ if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
+ new_reph_pos++;
+ goto reph_move;
+ }
+ }
+
+ /* 3. If reph should be repositioned after the main consonant: find the
+ * first consonant not ligated with main, or find the first
+ * consonant that is not a potential pre-base reordering Ra.
+ */
+ if (reph_pos == REPH_POS_AFTER_MAIN)
+ {
+ new_reph_pos = base;
+ /* XXX Skip potential pre-base reordering Ra. */
+ while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
+ new_reph_pos++;
+ if (new_reph_pos < end)
+ goto reph_move;
+ }
+
+ /* 4. If reph should be positioned before post-base consonant, find
+ * first post-base classified consonant not ligated with main. If no
+ * consonant is found, the target position should be before the
+ * first matra, syllable modifier sign or vedic sign.
+ */
+ /* This is our take on what step 4 is trying to say (and failing, BADLY). */
+ if (reph_pos == REPH_POS_AFTER_SUB)
+ {
+ new_reph_pos = base;
+ while (new_reph_pos < end &&
+ !( FLAG (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD))))
+ new_reph_pos++;
+ if (new_reph_pos < end)
+ goto reph_move;
+ }
+
+ /* 5. If no consonant is found in steps 3 or 4, move reph to a position
+ * immediately before the first post-base matra, syllable modifier
+ * sign or vedic sign that has a reordering class after the intended
+ * reph position. For example, if the reordering position for reph
+ * is post-main, it will skip above-base matras that also have a
+ * post-main position.
+ */
+ reph_step_5:
+ {
+ /* Copied from step 2. */
+ new_reph_pos = start + 1;
+ while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
+ new_reph_pos++;
+
+ if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
+ {
+ /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
+ if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
+ new_reph_pos++;
+ goto reph_move;
+ }
+ }
+
+ /* 6. Otherwise, reorder reph to the end of the syllable.
+ */
+ {
+ new_reph_pos = end - 1;
+ while (new_reph_pos > start && info[new_reph_pos].indic_position() == POS_SMVD)
+ new_reph_pos--;
+
+ /*
+ * If the Reph is to be ending up after a Matra,Halant sequence,
+ * position it before that Halant so it can interact with the Matra.
+ * However, if it's a plain Consonant,Halant we shouldn't do that.
+ * Uniscribe doesn't do this.
+ * TEST: U+0930,U+094D,U+0915,U+094B,U+094D
+ */
+ if (!hb_options ().uniscribe_bug_compatible &&
+ unlikely (is_halant_or_coeng (info[new_reph_pos]))) {
+ for (unsigned int i = base + 1; i < new_reph_pos; i++)
+ if (info[i].indic_category() == OT_M) {
+ /* Ok, got it. */
+ new_reph_pos--;
+ }
+ }
+ goto reph_move;
+ }
+
+ reph_move:
+ {
+ /* Yay, one big cluster! Merge before moving. */
+ buffer->merge_clusters (start, end);
+
+ /* Move */
+ hb_glyph_info_t reph = info[start];
+ memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (info[0]));
+ info[new_reph_pos] = reph;
+ if (start < base && base <= new_reph_pos)
+ base--;
+ }
+ }
+
+
+ /* o Reorder pre-base reordering consonants:
+ *
+ * If a pre-base reordering consonant is found, reorder it according to
+ * the following rules:
+ */
+
+ if (indic_plan->mask_array[PREF] && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
+ {
+ for (unsigned int i = base + 1; i < end; i++)
+ if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
+ {
+ /* 1. Only reorder a glyph produced by substitution during application
+ * of the <pref> feature. (Note that a font may shape a Ra consonant with
+ * the feature generally but block it in certain contexts.)
+ */
+ if (i + 1 == end || (info[i + 1].mask & indic_plan->mask_array[PREF]) == 0)
+ {
+ /*
+ * 2. Try to find a target position the same way as for pre-base matra.
+ * If it is found, reorder pre-base consonant glyph.
+ *
+ * 3. If position is not found, reorder immediately before main
+ * consonant.
+ */
+
+ unsigned int new_pos = base;
+ /* Malayalam / Tamil do not have "half" forms or explicit virama forms.
+ * The glyphs formed by 'half' are Chillus or ligated explicit viramas.
+ * We want to position matra after them.
+ */
+ if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
+ {
+ while (new_pos > start &&
+ !(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS)))
+ new_pos--;
+
+ /* In Khmer coeng model, a V,Ra can go *after* matras. If it goes after a
+ * split matra, it should be reordered to *before* the left part of such matra. */
+ if (new_pos > start && info[new_pos - 1].indic_category() == OT_M)
+ {
+ unsigned int old_pos = i;
+ for (unsigned int i = base + 1; i < old_pos; i++)
+ if (info[i].indic_category() == OT_M)
+ {
+ new_pos--;
+ break;
+ }
+ }
+ }
+
+ if (new_pos > start && is_halant_or_coeng (info[new_pos - 1]))
+ {
+ /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
+ if (new_pos < end && is_joiner (info[new_pos]))
+ new_pos++;
+ }
+
+ {
+ unsigned int old_pos = i;
+ buffer->merge_clusters (new_pos, old_pos + 1);
+ hb_glyph_info_t tmp = info[old_pos];
+ memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0]));
+ info[new_pos] = tmp;
+ if (new_pos <= base && base < old_pos)
+ base++;
+ }
+ }
+
+ break;
+ }
+ }
+
+
+ /* Apply 'init' to the Left Matra if it's a word start. */
+ if (info[start].indic_position () == POS_PRE_M &&
+ (!start ||
+ !(FLAG (_hb_glyph_info_get_general_category (&info[start - 1])) &
+ FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))))
+ info[start].mask |= indic_plan->mask_array[INIT];
+
+
+ /*
+ * Finish off the clusters and go home!
+ */
+ if (hb_options ().uniscribe_bug_compatible)
+ {
+ /* Uniscribe merges the entire cluster.
+ * This means, half forms are submerged into the main consonants cluster.
+ * This is unnecessary, and makes cursor positioning harder, but that's what
+ * Uniscribe does. */
+ buffer->merge_clusters (start, end);
+ }
+}
+
+
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int last = 0;
+ unsigned int last_syllable = info[0].syllable();
+ for (unsigned int i = 1; i < count; i++)
+ if (last_syllable != info[i].syllable()) {
+ final_reordering_syllable (plan, buffer, last, i);
+ last = i;
+ last_syllable = info[last].syllable();
+ }
+ final_reordering_syllable (plan, buffer, last, count);
+
+ /* Zero syllables now... */
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
+}
+
+
+static hb_ot_shape_normalization_mode_t
+normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
+{
+ return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+}
+
+static bool
+decompose_indic (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b)
+{
+ switch (ab)
+ {
+ /* Don't decompose these. */
+ case 0x0931 : return false;
+ case 0x0B94 : return false;
+
+
+ /*
+ * Decompose split matras that don't have Unicode decompositions.
+ */
+
+ case 0x0F77 : *a = 0x0FB2; *b= 0x0F81; return true;
+ case 0x0F79 : *a = 0x0FB3; *b= 0x0F81; return true;
+ case 0x17BE : *a = 0x17C1; *b= 0x17BE; return true;
+ case 0x17BF : *a = 0x17C1; *b= 0x17BF; return true;
+ case 0x17C0 : *a = 0x17C1; *b= 0x17C0; return true;
+ case 0x17C4 : *a = 0x17C1; *b= 0x17C4; return true;
+ case 0x17C5 : *a = 0x17C1; *b= 0x17C5; return true;
+ case 0x1925 : *a = 0x1920; *b= 0x1923; return true;
+ case 0x1926 : *a = 0x1920; *b= 0x1924; return true;
+ case 0x1B3C : *a = 0x1B42; *b= 0x1B3C; return true;
+ case 0x1112E : *a = 0x11127; *b= 0x11131; return true;
+ case 0x1112F : *a = 0x11127; *b= 0x11132; return true;
+#if 0
+ /* This one has no decomposition in Unicode, but needs no decomposition either. */
+ /* case 0x0AC9 : return false; */
+ case 0x0B57 : *a = no decomp, -> RIGHT; return true;
+ case 0x1C29 : *a = no decomp, -> LEFT; return true;
+ case 0xA9C0 : *a = no decomp, -> RIGHT; return true;
+ case 0x111BF : *a = no decomp, -> ABOVE; return true;
+#endif
+ }
+
+ if ((ab == 0x0DDA || hb_in_range<hb_codepoint_t> (ab, 0x0DDC, 0x0DDE)))
+ {
+ /*
+ * Sinhala split matras... Let the fun begin.
+ *
+ * These four characters have Unicode decompositions. However, Uniscribe
+ * decomposes them "Khmer-style", that is, it uses the character itself to
+ * get the second half. The first half of all four decompositions is always
+ * U+0DD9.
+ *
+ * Now, there are buggy fonts, namely, the widely used lklug.ttf, that are
+ * broken with Uniscribe. But we need to support them. As such, we only
+ * do the Uniscribe-style decomposition if the character is transformed into
+ * its "sec.half" form by the 'pstf' feature. Otherwise, we fall back to
+ * Unicode decomposition.
+ *
+ * Note that we can't unconditionally use Unicode decomposition. That would
+ * break some other fonts, that are designed to work with Uniscribe, and
+ * don't have positioning features for the Unicode-style decomposition.
+ *
+ * Argh...
+ *
+ * The Uniscribe behavior is now documented in the newly published Sinhala
+ * spec in 2012:
+ *
+ * http://www.microsoft.com/typography/OpenTypeDev/sinhala/intro.htm#shaping
+ */
+
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
+
+ hb_codepoint_t glyph;
+
+ if (hb_options ().uniscribe_bug_compatible ||
+ (c->font->get_glyph (ab, 0, &glyph) &&
+ indic_plan->pstf.would_substitute (&glyph, 1, true, c->font->face)))
+ {
+ /* Ok, safe to use Uniscribe-style decomposition. */
+ *a = 0x0DD9;
+ *b = ab;
+ return true;
+ }
+ }
+
+ return c->unicode->decompose (ab, a, b);
+}
+
+static bool
+compose_indic (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
+{
+ /* Avoid recomposing split matras. */
+ if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a)))
+ return false;
+
+ /* Composition-exclusion exceptions that we want to recompose. */
+ if (a == 0x09AF && b == 0x09BC) { *ab = 0x09DF; return true; }
+
+ return c->unicode->compose (a, b, ab);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
+{
+ "indic",
+ collect_features_indic,
+ override_features_indic,
+ data_create_indic,
+ data_destroy_indic,
+ NULL, /* preprocess_text */
+ normalization_preference_indic,
+ decompose_indic,
+ compose_indic,
+ setup_masks_indic,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+ false, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
new file mode 100644
index 0000000000..e282f0cfb1
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -0,0 +1,391 @@
+
+#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
+static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
+ 1u, 30u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
+ 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
+ 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
+ 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
+ 3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
+ 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 0
+};
+
+static const char _myanmar_syllable_machine_key_spans[] = {
+ 30, 28, 25, 4, 25, 23, 21, 21,
+ 27, 27, 27, 27, 16, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 25, 4,
+ 25, 23, 21, 21, 27, 27, 27, 27,
+ 28, 27, 30, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27
+};
+
+static const short _myanmar_syllable_machine_index_offsets[] = {
+ 0, 31, 60, 86, 91, 117, 141, 163,
+ 185, 213, 241, 269, 297, 314, 342, 370,
+ 398, 426, 454, 482, 510, 538, 566, 592,
+ 597, 623, 647, 669, 691, 719, 747, 775,
+ 803, 832, 860, 891, 919, 947, 975, 1003,
+ 1031, 1059, 1087, 1115
+};
+
+static const char _myanmar_syllable_machine_indicies[] = {
+ 1, 1, 2, 3, 4, 4, 0, 5,
+ 0, 6, 0, 1, 0, 0, 0, 7,
+ 0, 8, 1, 0, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 0, 20,
+ 21, 22, 22, 19, 23, 19, 24, 19,
+ 19, 19, 19, 19, 19, 19, 25, 19,
+ 19, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 19, 22, 22, 19, 23,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 36, 19, 19, 19, 19, 19, 19,
+ 30, 19, 19, 19, 34, 19, 22, 22,
+ 19, 23, 19, 22, 22, 19, 23, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 30,
+ 19, 19, 19, 34, 19, 37, 19, 22,
+ 22, 19, 23, 19, 30, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 30, 19, 22, 22, 19,
+ 23, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 38, 19, 19, 19, 19, 19,
+ 19, 30, 19, 22, 22, 19, 23, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 30,
+ 19, 20, 19, 22, 22, 19, 23, 19,
+ 24, 19, 19, 19, 19, 19, 19, 19,
+ 39, 19, 19, 39, 19, 19, 19, 30,
+ 40, 19, 19, 34, 19, 20, 19, 22,
+ 22, 19, 23, 19, 24, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 30, 19, 19, 19, 34,
+ 19, 20, 19, 22, 22, 19, 23, 19,
+ 24, 19, 19, 19, 19, 19, 19, 19,
+ 39, 19, 19, 19, 19, 19, 19, 30,
+ 40, 19, 19, 34, 19, 20, 19, 22,
+ 22, 19, 23, 19, 24, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 30, 40, 19, 19, 34,
+ 19, 1, 1, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 1, 19, 20, 19, 22, 22, 19, 23,
+ 19, 24, 19, 19, 19, 19, 19, 19,
+ 19, 25, 19, 19, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 19, 20, 19,
+ 22, 22, 19, 23, 19, 24, 19, 19,
+ 19, 19, 19, 19, 19, 33, 19, 19,
+ 19, 19, 19, 19, 30, 31, 32, 33,
+ 34, 19, 20, 19, 22, 22, 19, 23,
+ 19, 24, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 30, 31, 32, 33, 34, 19, 20, 19,
+ 22, 22, 19, 23, 19, 24, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 30, 31, 32, 19,
+ 34, 19, 20, 19, 22, 22, 19, 23,
+ 19, 24, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 30, 19, 32, 19, 34, 19, 20, 19,
+ 22, 22, 19, 23, 19, 24, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 26, 19, 28, 19, 30, 31, 32, 33,
+ 34, 19, 20, 19, 22, 22, 19, 23,
+ 19, 24, 19, 19, 19, 19, 19, 19,
+ 19, 33, 19, 19, 26, 19, 19, 19,
+ 30, 31, 32, 33, 34, 19, 20, 19,
+ 22, 22, 19, 23, 19, 24, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 26, 27, 28, 19, 30, 31, 32, 33,
+ 34, 19, 20, 21, 22, 22, 19, 23,
+ 19, 24, 19, 19, 19, 19, 19, 19,
+ 19, 25, 19, 19, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 19, 3, 3,
+ 41, 5, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 42, 41, 41, 41, 41,
+ 41, 41, 13, 41, 41, 41, 17, 41,
+ 3, 3, 41, 5, 41, 3, 3, 41,
+ 5, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 13, 41, 41, 41, 17, 41, 43,
+ 41, 3, 3, 41, 5, 41, 13, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 13, 41, 3,
+ 3, 41, 5, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 44, 41, 41, 41,
+ 41, 41, 41, 13, 41, 3, 3, 41,
+ 5, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 13, 41, 2, 41, 3, 3, 41,
+ 5, 41, 6, 41, 41, 41, 41, 41,
+ 41, 41, 45, 41, 41, 45, 41, 41,
+ 41, 13, 46, 41, 41, 17, 41, 2,
+ 41, 3, 3, 41, 5, 41, 6, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 13, 41, 41,
+ 41, 17, 41, 2, 41, 3, 3, 41,
+ 5, 41, 6, 41, 41, 41, 41, 41,
+ 41, 41, 45, 41, 41, 41, 41, 41,
+ 41, 13, 46, 41, 41, 17, 41, 2,
+ 41, 3, 3, 41, 5, 41, 6, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 13, 46, 41,
+ 41, 17, 41, 20, 21, 22, 22, 19,
+ 23, 19, 24, 19, 19, 19, 19, 19,
+ 19, 19, 47, 19, 19, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 19,
+ 20, 48, 22, 22, 19, 23, 19, 24,
+ 19, 19, 19, 19, 19, 19, 19, 25,
+ 19, 19, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 19, 1, 1, 2, 3,
+ 3, 3, 41, 5, 41, 6, 41, 1,
+ 41, 41, 41, 1, 41, 8, 1, 41,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 41, 2, 41, 3, 3, 41,
+ 5, 41, 6, 41, 41, 41, 41, 41,
+ 41, 41, 8, 41, 41, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 41, 2,
+ 41, 3, 3, 41, 5, 41, 6, 41,
+ 41, 41, 41, 41, 41, 41, 16, 41,
+ 41, 41, 41, 41, 41, 13, 14, 15,
+ 16, 17, 41, 2, 41, 3, 3, 41,
+ 5, 41, 6, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 13, 14, 15, 16, 17, 41, 2,
+ 41, 3, 3, 41, 5, 41, 6, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 13, 14, 15,
+ 41, 17, 41, 2, 41, 3, 3, 41,
+ 5, 41, 6, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 13, 41, 15, 41, 17, 41, 2,
+ 41, 3, 3, 41, 5, 41, 6, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 9, 41, 11, 41, 13, 14, 15,
+ 16, 17, 41, 2, 41, 3, 3, 41,
+ 5, 41, 6, 41, 41, 41, 41, 41,
+ 41, 41, 16, 41, 41, 9, 41, 41,
+ 41, 13, 14, 15, 16, 17, 41, 2,
+ 41, 3, 3, 41, 5, 41, 6, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 9, 10, 11, 41, 13, 14, 15,
+ 16, 17, 41, 2, 3, 3, 3, 41,
+ 5, 41, 6, 41, 41, 41, 41, 41,
+ 41, 41, 8, 41, 41, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 41, 0
+};
+
+static const char _myanmar_syllable_machine_trans_targs[] = {
+ 0, 1, 22, 0, 0, 23, 29, 32,
+ 35, 36, 40, 41, 42, 25, 38, 39,
+ 37, 28, 43, 0, 2, 12, 0, 3,
+ 9, 13, 14, 18, 19, 20, 5, 16,
+ 17, 15, 8, 21, 4, 6, 7, 10,
+ 11, 0, 24, 26, 27, 30, 31, 33,
+ 34
+};
+
+static const char _myanmar_syllable_machine_trans_actions[] = {
+ 3, 0, 0, 4, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+static const char _myanmar_syllable_machine_to_state_actions[] = {
+ 1, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static const char _myanmar_syllable_machine_from_state_actions[] = {
+ 2, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static const short _myanmar_syllable_machine_eof_trans[] = {
+ 0, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 20, 20, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42
+};
+
+static const int myanmar_syllable_machine_start = 0;
+static const int myanmar_syllable_machine_first_final = 0;
+static const int myanmar_syllable_machine_error = -1;
+
+static const int myanmar_syllable_machine_en_main = 0;
+
+
+#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+
+#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+ for (unsigned int i = last; i < p+1; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ last = p+1; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 288 "hb-ot-shape-complex-myanmar-machine.hh"
+ {
+ cs = myanmar_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 111 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int last = 0;
+ unsigned int syllable_serial = 1;
+
+#line 305 "hb-ot-shape-complex-myanmar-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
+ case 2:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 319 "hb-ot-shape-complex-myanmar-machine.hh"
+ }
+
+ _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
+ _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
+
+ _slen = _myanmar_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
+ ( info[p].myanmar_category()) <= _keys[1] ?
+ ( info[p].myanmar_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _myanmar_syllable_machine_trans_targs[_trans];
+
+ if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
+ case 7:
+#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (consonant_syllable); }}
+ break;
+ case 5:
+#line 84 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (non_myanmar_cluster); }}
+ break;
+ case 4:
+#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (broken_cluster); }}
+ break;
+ case 3:
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (non_myanmar_cluster); }}
+ break;
+ case 6:
+#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (consonant_syllable); }}
+ break;
+ case 8:
+#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (broken_cluster); }}
+ break;
+#line 361 "hb-ot-shape-complex-myanmar-machine.hh"
+ }
+
+_again:
+ switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
+ case 1:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 120 "hb-ot-shape-complex-myanmar-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
new file mode 100644
index 0000000000..29f29bb556
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
@@ -0,0 +1,534 @@
+/*
+ * Copyright © 2011,2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+
+/* buffer var allocations */
+#define myanmar_category() complex_var_u8_0() /* myanmar_category_t */
+#define myanmar_position() complex_var_u8_1() /* myanmar_position_t */
+
+
+/*
+ * Myanmar shaper.
+ */
+
+static const hb_tag_t
+basic_features[] =
+{
+ /*
+ * Basic features.
+ * These features are applied in order, one at a time, after initial_reordering.
+ */
+ HB_TAG('r','p','h','f'),
+ HB_TAG('p','r','e','f'),
+ HB_TAG('b','l','w','f'),
+ HB_TAG('p','s','t','f'),
+};
+static const hb_tag_t
+other_features[] =
+{
+ /*
+ * Other features.
+ * These features are applied all at once, after final_reordering.
+ */
+ HB_TAG('p','r','e','s'),
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('p','s','t','s'),
+ /* Positioning features, though we don't care about the types. */
+ HB_TAG('d','i','s','t'),
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
+collect_features_myanmar (hb_ot_shape_planner_t *plan)
+{
+ hb_ot_map_builder_t *map = &plan->map;
+
+ /* Do this before any lookups have been applied. */
+ map->add_gsub_pause (setup_syllables);
+
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+ /* The Indic specs do not require ccmp, but we apply it here since if
+ * there is a use of it, it's typically at the beginning. */
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+
+
+ map->add_gsub_pause (initial_reordering);
+ for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
+ {
+ map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+ map->add_gsub_pause (NULL);
+ }
+ map->add_gsub_pause (final_reordering);
+ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+ map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+}
+
+static void
+override_features_myanmar (hb_ot_shape_planner_t *plan)
+{
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+}
+
+
+enum syllable_type_t {
+ consonant_syllable,
+ broken_cluster,
+ non_myanmar_cluster,
+};
+
+#include "hb-ot-shape-complex-myanmar-machine.hh"
+
+
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum myanmar_category_t {
+ OT_As = 18, /* Asat */
+ OT_D = 19, /* Digits except zero */
+ OT_D0 = 20, /* Digit zero */
+ OT_DB = OT_N, /* Dot below */
+ OT_GB = OT_DOTTEDCIRCLE,
+ OT_MH = 21, /* Various consonant medial types */
+ OT_MR = 22, /* Various consonant medial types */
+ OT_MW = 23, /* Various consonant medial types */
+ OT_MY = 24, /* Various consonant medial types */
+ OT_PT = 25, /* Pwo and other tones */
+ OT_VAbv = 26,
+ OT_VBlw = 27,
+ OT_VPre = 28,
+ OT_VPst = 29,
+ OT_VS = 30 /* Variation selectors */
+};
+
+
+static inline bool
+is_one_of (const hb_glyph_info_t &info, unsigned int flags)
+{
+ /* If it ligated, all bets are off. */
+ if (is_a_ligature (info)) return false;
+ return !!(FLAG (info.myanmar_category()) & flags);
+}
+
+/* Note:
+ *
+ * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
+ * cannot happen in a consonant syllable. The plus side however is, we can call the
+ * consonant syllable logic from the vowel syllable function and get it all right! */
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_GB))
+static inline bool
+is_consonant (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, CONSONANT_FLAGS);
+}
+
+
+static inline void
+set_myanmar_properties (hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+ indic_category_t cat = (indic_category_t) (type & 0x7F);
+ indic_position_t pos = (indic_position_t) (type >> 8);
+
+ /* Myanmar
+ * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
+ */
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00, 0xFE0F)))
+ cat = (indic_category_t) OT_VS;
+ else if (unlikely (u == 0x200C)) cat = (indic_category_t) OT_ZWNJ;
+ else if (unlikely (u == 0x200D)) cat = (indic_category_t) OT_ZWJ;
+
+ switch (u)
+ {
+ case 0x002D: case 0x00A0: case 0x00D7: case 0x2012:
+ case 0x2013: case 0x2014: case 0x2015: case 0x2022:
+ case 0x25CC: case 0x25FB: case 0x25FC: case 0x25FD:
+ case 0x25FE:
+ cat = (indic_category_t) OT_GB;
+ break;
+
+ case 0x1004: case 0x101B: case 0x105A:
+ cat = (indic_category_t) OT_Ra;
+ break;
+
+ case 0x1032: case 0x1036:
+ cat = (indic_category_t) OT_A;
+ break;
+
+ case 0x103A:
+ cat = (indic_category_t) OT_As;
+ break;
+
+ case 0x1041: case 0x1042: case 0x1043: case 0x1044:
+ case 0x1045: case 0x1046: case 0x1047: case 0x1048:
+ case 0x1049: case 0x1090: case 0x1091: case 0x1092:
+ case 0x1093: case 0x1094: case 0x1095: case 0x1096:
+ case 0x1097: case 0x1098: case 0x1099:
+ cat = (indic_category_t) OT_D;
+ break;
+
+ case 0x1040:
+ cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
+ break;
+
+ case 0x103E: case 0x1060:
+ cat = (indic_category_t) OT_MH;
+ break;
+
+ case 0x103C:
+ cat = (indic_category_t) OT_MR;
+ break;
+
+ case 0x103D: case 0x1082:
+ cat = (indic_category_t) OT_MW;
+ break;
+
+ case 0x103B: case 0x105E: case 0x105F:
+ cat = (indic_category_t) OT_MY;
+ break;
+
+ case 0x1063: case 0x1064: case 0x1069: case 0x106A:
+ case 0x106B: case 0x106C: case 0x106D: case 0xAA7B:
+ cat = (indic_category_t) OT_PT;
+ break;
+
+ case 0x1038: case 0x1087: case 0x1088: case 0x1089:
+ case 0x108A: case 0x108B: case 0x108C: case 0x108D:
+ case 0x108F: case 0x109A: case 0x109B: case 0x109C:
+ cat = (indic_category_t) OT_SM;
+ break;
+ }
+
+ if (cat == OT_M)
+ {
+ switch ((int) pos)
+ {
+ case POS_PRE_C: cat = (indic_category_t) OT_VPre;
+ pos = POS_PRE_M; break;
+ case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break;
+ case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break;
+ case POS_POST_C: cat = (indic_category_t) OT_VPst; break;
+ }
+ }
+
+ info.myanmar_category() = (myanmar_category_t) cat;
+ info.myanmar_position() = pos;
+}
+
+
+
+static void
+setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
+ HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
+
+ /* We cannot setup masks here. We save information about characters
+ * and setup masks later on in a pause-callback. */
+
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ set_myanmar_properties (buffer->info[i]);
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ find_syllables (buffer);
+}
+
+static int
+compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+ int a = pa->myanmar_position();
+ int b = pb->myanmar_position();
+
+ return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+/* Rules from:
+ * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */
+
+static void
+initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ hb_glyph_info_t *info = buffer->info;
+
+ unsigned int base = end;
+ bool has_reph = false;
+
+ {
+ unsigned int limit = start;
+ if (start + 3 <= end &&
+ info[start ].myanmar_category() == OT_Ra &&
+ info[start+1].myanmar_category() == OT_As &&
+ info[start+2].myanmar_category() == OT_H)
+ {
+ limit += 3;
+ base = start;
+ has_reph = true;
+ }
+
+ {
+ if (!has_reph)
+ base = limit;
+
+ for (unsigned int i = limit; i < end; i++)
+ if (is_consonant (info[i]))
+ {
+ base = i;
+ break;
+ }
+ }
+ }
+
+ /* Reorder! */
+ {
+ unsigned int i = start;
+ for (; i < start + (has_reph ? 3 : 0); i++)
+ info[i].myanmar_position() = POS_AFTER_MAIN;
+ for (; i < base; i++)
+ info[i].myanmar_position() = POS_PRE_C;
+ if (i < end)
+ {
+ info[i].myanmar_position() = POS_BASE_C;
+ i++;
+ }
+ indic_position_t pos = POS_AFTER_MAIN;
+ /* The following loop may be ugly, but it implements all of
+ * Myanmar reordering! */
+ for (; i < end; i++)
+ {
+ if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */
+ {
+ info[i].myanmar_position() = POS_PRE_C;
+ continue;
+ }
+ if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */
+ {
+ continue;
+ }
+
+ if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw)
+ {
+ pos = POS_BELOW_C;
+ info[i].myanmar_position() = pos;
+ continue;
+ }
+
+ if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A)
+ {
+ info[i].myanmar_position() = POS_BEFORE_SUB;
+ continue;
+ }
+ if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw)
+ {
+ info[i].myanmar_position() = pos;
+ continue;
+ }
+ if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
+ {
+ pos = POS_AFTER_SUB;
+ info[i].myanmar_position() = pos;
+ continue;
+ }
+ info[i].myanmar_position() = pos;
+ }
+ }
+
+ buffer->merge_clusters (start, end);
+ /* Sit tight, rock 'n roll! */
+ hb_bubble_sort (info + start, end - start, compare_myanmar_order);
+}
+
+static void
+initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ /* We already inserted dotted-circles, so just call the consonant_syllable. */
+ initial_reordering_consonant_syllable (plan, face, buffer, start, end);
+}
+
+static void
+initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ hb_buffer_t *buffer HB_UNUSED,
+ unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
+{
+ /* Nothing to do right now. If we ever switch to using the output
+ * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+
+static void
+initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+ switch (syllable_type) {
+ case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
+ case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
+ case non_myanmar_cluster: initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return;
+ }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ /* Note: This loop is extra overhead, but should not be measurable. */
+ bool has_broken_syllables = false;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
+ has_broken_syllables = true;
+ break;
+ }
+ if (likely (!has_broken_syllables))
+ return;
+
+
+ hb_codepoint_t dottedcircle_glyph;
+ if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
+ return;
+
+ hb_glyph_info_t dottedcircle = {0};
+ dottedcircle.codepoint = 0x25CC;
+ set_myanmar_properties (dottedcircle);
+ dottedcircle.codepoint = dottedcircle_glyph;
+
+ buffer->clear_output ();
+
+ buffer->idx = 0;
+ unsigned int last_syllable = 0;
+ while (buffer->idx < buffer->len)
+ {
+ unsigned int syllable = buffer->cur().syllable();
+ syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+ if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+ {
+ last_syllable = syllable;
+
+ hb_glyph_info_t info = dottedcircle;
+ info.cluster = buffer->cur().cluster;
+ info.mask = buffer->cur().mask;
+ info.syllable() = buffer->cur().syllable();
+
+ buffer->output_info (info);
+ }
+ else
+ buffer->next_glyph ();
+ }
+
+ buffer->swap_buffers ();
+}
+
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ insert_dotted_circles (plan, font, buffer);
+
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+ unsigned int last = 0;
+ unsigned int last_syllable = info[0].syllable();
+ for (unsigned int i = 1; i < count; i++)
+ if (last_syllable != info[i].syllable()) {
+ initial_reordering_syllable (plan, font->face, buffer, last, i);
+ last = i;
+ last_syllable = info[last].syllable();
+ }
+ initial_reordering_syllable (plan, font->face, buffer, last, count);
+}
+
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+
+ /* Zero syllables now... */
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
+}
+
+
+static hb_ot_shape_normalization_mode_t
+normalization_preference_myanmar (const hb_segment_properties_t *props HB_UNUSED)
+{
+ return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
+{
+ "myanmar",
+ collect_features_myanmar,
+ override_features_myanmar,
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ NULL, /* preprocess_text */
+ normalization_preference_myanmar,
+ NULL, /* decompose */
+ NULL, /* compose */
+ setup_masks_myanmar,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
+ false, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
new file mode 100644
index 0000000000..a099e05d74
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
@@ -0,0 +1,359 @@
+/*
+ * Copyright © 2010,2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-normalize-private.hh"
+
+
+
+/* buffer var allocations, used by complex shapers */
+#define complex_var_u8_0() var2.u8[2]
+#define complex_var_u8_1() var2.u8[3]
+
+
+enum hb_ot_shape_zero_width_marks_type_t {
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
+};
+
+
+/* Master OT shaper list */
+#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
+ HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
+ HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (sea) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
+ /* ^--- Add new shapers here */
+
+
+struct hb_ot_complex_shaper_t
+{
+ char name[8];
+
+ /* collect_features()
+ * Called during shape_plan().
+ * Shapers should use plan->map to add their features and callbacks.
+ * May be NULL.
+ */
+ void (*collect_features) (hb_ot_shape_planner_t *plan);
+
+ /* override_features()
+ * Called during shape_plan().
+ * Shapers should use plan->map to override features and add callbacks after
+ * common features are added.
+ * May be NULL.
+ */
+ void (*override_features) (hb_ot_shape_planner_t *plan);
+
+
+ /* data_create()
+ * Called at the end of shape_plan().
+ * Whatever shapers return will be accessible through plan->data later.
+ * If NULL is returned, means a plan failure.
+ */
+ void *(*data_create) (const hb_ot_shape_plan_t *plan);
+
+ /* data_destroy()
+ * Called when the shape_plan is being destroyed.
+ * plan->data is passed here for destruction.
+ * If NULL is returned, means a plan failure.
+ * May be NULL.
+ */
+ void (*data_destroy) (void *data);
+
+
+ /* preprocess_text()
+ * Called during shape().
+ * Shapers can use to modify text before shaping starts.
+ * May be NULL.
+ */
+ void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font);
+
+
+ /* normalization_preference()
+ * Called during shape().
+ * May be NULL.
+ */
+ hb_ot_shape_normalization_mode_t
+ (*normalization_preference) (const hb_segment_properties_t *props);
+
+ /* decompose()
+ * Called during shape()'s normalization.
+ * May be NULL.
+ */
+ bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b);
+
+ /* compose()
+ * Called during shape()'s normalization.
+ * May be NULL.
+ */
+ bool (*compose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab);
+
+ /* setup_masks()
+ * Called during shape().
+ * Shapers should use map to get feature masks and set on buffer.
+ * Shapers may NOT modify characters.
+ * May be NULL.
+ */
+ void (*setup_masks) (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font);
+
+ hb_ot_shape_zero_width_marks_type_t zero_width_marks;
+
+ bool fallback_position;
+};
+
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
+HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
+
+
+static inline const hb_ot_complex_shaper_t *
+hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
+{
+ switch ((hb_tag_t) planner->props.script)
+ {
+ default:
+ return &_hb_ot_complex_shaper_default;
+
+
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_ARABIC:
+
+ /* Unicode-3.0 additions */
+ case HB_SCRIPT_MONGOLIAN:
+ case HB_SCRIPT_SYRIAC:
+
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_NKO:
+ case HB_SCRIPT_PHAGS_PA:
+
+ /* Unicode-6.0 additions */
+ case HB_SCRIPT_MANDAIC:
+
+ /* For Arabic script, use the Arabic shaper even if no OT script tag was found.
+ * This is because we do fallback shaping for Arabic script (and not others). */
+ if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
+ planner->props.script == HB_SCRIPT_ARABIC)
+ return &_hb_ot_complex_shaper_arabic;
+ else
+ return &_hb_ot_complex_shaper_default;
+
+
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_THAI:
+ case HB_SCRIPT_LAO:
+
+ return &_hb_ot_complex_shaper_thai;
+
+
+#if 0
+ /* Note:
+ * Currently we don't have a separate Hangul shaper. The default shaper handles
+ * Hangul by enabling jamo features. We may want to implement a separate shaper
+ * in the future. See this thread for details of what such a shaper would do:
+ *
+ * http://lists.freedesktop.org/archives/harfbuzz/2013-April/003070.html
+ */
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_HANGUL:
+
+ return &_hb_ot_complex_shaper_hangul;
+#endif
+
+
+ /* ^--- Add new shapers here */
+
+
+#if 0
+ /* Note:
+ *
+ * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according
+ * to Martin Hosken and Jonathan Kew do not require complex shaping.
+ *
+ * TODO We should automate figuring out which scripts do not need complex shaping
+ *
+ * TODO We currently keep data for these scripts in our indic table. Need to fix the
+ * generator to not do that.
+ */
+
+
+ /* Simple? */
+
+ /* Unicode-3.2 additions */
+ case HB_SCRIPT_BUHID:
+ case HB_SCRIPT_HANUNOO:
+
+ /* Unicode-5.1 additions */
+ case HB_SCRIPT_SAURASHTRA:
+
+ /* Unicode-6.0 additions */
+ case HB_SCRIPT_BATAK:
+ case HB_SCRIPT_BRAHMI:
+
+
+ /* Simple */
+
+ /* Unicode-1.1 additions */
+ /* These have their own shaper now. */
+ case HB_SCRIPT_LAO:
+ case HB_SCRIPT_THAI:
+
+ /* Unicode-2.0 additions */
+ case HB_SCRIPT_TIBETAN:
+
+ /* Unicode-3.2 additions */
+ case HB_SCRIPT_TAGALOG:
+ case HB_SCRIPT_TAGBANWA:
+
+ /* Unicode-4.0 additions */
+ case HB_SCRIPT_LIMBU:
+ case HB_SCRIPT_TAI_LE:
+
+ /* Unicode-4.1 additions */
+ case HB_SCRIPT_KHAROSHTHI:
+ case HB_SCRIPT_SYLOTI_NAGRI:
+
+ /* Unicode-5.1 additions */
+ case HB_SCRIPT_KAYAH_LI:
+
+ /* Unicode-5.2 additions */
+ case HB_SCRIPT_TAI_VIET:
+
+
+#endif
+
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_BENGALI:
+ case HB_SCRIPT_DEVANAGARI:
+ case HB_SCRIPT_GUJARATI:
+ case HB_SCRIPT_GURMUKHI:
+ case HB_SCRIPT_KANNADA:
+ case HB_SCRIPT_MALAYALAM:
+ case HB_SCRIPT_ORIYA:
+ case HB_SCRIPT_TAMIL:
+ case HB_SCRIPT_TELUGU:
+
+ /* Unicode-3.0 additions */
+ case HB_SCRIPT_SINHALA:
+
+ /* Unicode-4.1 additions */
+ case HB_SCRIPT_BUGINESE:
+
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_BALINESE:
+
+ /* Unicode-5.1 additions */
+ case HB_SCRIPT_LEPCHA:
+ case HB_SCRIPT_REJANG:
+ case HB_SCRIPT_SUNDANESE:
+
+ /* Unicode-5.2 additions */
+ case HB_SCRIPT_JAVANESE:
+ case HB_SCRIPT_KAITHI:
+ case HB_SCRIPT_MEETEI_MAYEK:
+
+ /* Unicode-6.0 additions */
+
+ /* Unicode-6.1 additions */
+ case HB_SCRIPT_CHAKMA:
+ case HB_SCRIPT_SHARADA:
+ case HB_SCRIPT_TAKRI:
+
+ /* If the designer designed the font for the 'DFLT' script,
+ * use the default shaper. Otherwise, use the Indic shaper.
+ * Note that for some simple scripts, there may not be *any*
+ * GSUB/GPOS needed, so there may be no scripts found! */
+ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+ return &_hb_ot_complex_shaper_default;
+ else
+ return &_hb_ot_complex_shaper_indic;
+
+ case HB_SCRIPT_KHMER:
+ /* A number of Khmer fonts in the wild don't have a 'pref' feature,
+ * and as such won't shape properly via the Indic shaper;
+ * however, they typically have 'liga' / 'clig' features that implement
+ * the necessary "reordering" by means of ligature substitutions.
+ * So we send such pref-less fonts through the generic shaper instead. */
+ if (planner->map.found_script[0] &&
+ hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
+ planner->map.script_index[0],
+ planner->map.language_index[0],
+ HB_TAG ('p','r','e','f'),
+ NULL))
+ return &_hb_ot_complex_shaper_indic;
+ else
+ return &_hb_ot_complex_shaper_default;
+
+ case HB_SCRIPT_MYANMAR:
+ /* For Myanmar, we only want to use the Myanmar shaper if the "new" script
+ * tag is found. For "old" script tag we want to use the default shaper. */
+ if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
+ return &_hb_ot_complex_shaper_myanmar;
+ else
+ return &_hb_ot_complex_shaper_default;
+
+ /* Unicode-4.1 additions */
+ case HB_SCRIPT_NEW_TAI_LUE:
+
+ /* Unicode-5.1 additions */
+ case HB_SCRIPT_CHAM:
+
+ /* Unicode-5.2 additions */
+ case HB_SCRIPT_TAI_THAM:
+
+ /* If the designer designed the font for the 'DFLT' script,
+ * use the default shaper. Otherwise, use the Indic shaper.
+ * Note that for some simple scripts, there may not be *any*
+ * GSUB/GPOS needed, so there may be no scripts found! */
+ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+ return &_hb_ot_complex_shaper_default;
+ else
+ return &_hb_ot_complex_shaper_sea;
+ }
+}
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh
new file mode 100644
index 0000000000..15b862f5a1
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh
@@ -0,0 +1,224 @@
+
+#line 1 "hb-ot-shape-complex-sea-machine.rl"
+/*
+ * Copyright © 2011,2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-ot-shape-complex-sea-machine.hh"
+static const unsigned char _sea_syllable_machine_trans_keys[] = {
+ 1u, 1u, 1u, 1u, 1u, 29u, 3u, 29u, 3u, 29u, 1u, 1u, 0
+};
+
+static const char _sea_syllable_machine_key_spans[] = {
+ 1, 1, 29, 27, 27, 1
+};
+
+static const char _sea_syllable_machine_index_offsets[] = {
+ 0, 2, 4, 34, 62, 90
+};
+
+static const char _sea_syllable_machine_indicies[] = {
+ 1, 0, 3, 2, 1, 1, 3, 5,
+ 4, 4, 4, 4, 4, 3, 4, 1,
+ 4, 4, 4, 4, 3, 4, 4, 4,
+ 4, 3, 4, 4, 4, 3, 3, 3,
+ 3, 4, 1, 7, 6, 6, 6, 6,
+ 6, 1, 6, 6, 6, 6, 6, 6,
+ 1, 6, 6, 6, 6, 1, 6, 6,
+ 6, 1, 1, 1, 1, 6, 3, 9,
+ 8, 8, 8, 8, 8, 3, 8, 8,
+ 8, 8, 8, 8, 3, 8, 8, 8,
+ 8, 3, 8, 8, 8, 3, 3, 3,
+ 3, 8, 3, 10, 0
+};
+
+static const char _sea_syllable_machine_trans_targs[] = {
+ 2, 3, 2, 4, 2, 5, 2, 0,
+ 2, 1, 2
+};
+
+static const char _sea_syllable_machine_trans_actions[] = {
+ 1, 2, 3, 2, 6, 0, 7, 0,
+ 8, 0, 9
+};
+
+static const char _sea_syllable_machine_to_state_actions[] = {
+ 0, 0, 4, 0, 0, 0
+};
+
+static const char _sea_syllable_machine_from_state_actions[] = {
+ 0, 0, 5, 0, 0, 0
+};
+
+static const char _sea_syllable_machine_eof_trans[] = {
+ 1, 3, 0, 7, 9, 11
+};
+
+static const int sea_syllable_machine_start = 2;
+static const int sea_syllable_machine_first_final = 2;
+static const int sea_syllable_machine_error = -1;
+
+static const int sea_syllable_machine_en_main = 2;
+
+
+#line 36 "hb-ot-shape-complex-sea-machine.rl"
+
+
+
+#line 67 "hb-ot-shape-complex-sea-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+ for (unsigned int i = last; i < p+1; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ last = p+1; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 117 "hb-ot-shape-complex-sea-machine.hh"
+ {
+ cs = sea_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 88 "hb-ot-shape-complex-sea-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int last = 0;
+ unsigned int syllable_serial = 1;
+
+#line 134 "hb-ot-shape-complex-sea-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _sea_syllable_machine_from_state_actions[cs] ) {
+ case 5:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 148 "hb-ot-shape-complex-sea-machine.hh"
+ }
+
+ _keys = _sea_syllable_machine_trans_keys + (cs<<1);
+ _inds = _sea_syllable_machine_indicies + _sea_syllable_machine_index_offsets[cs];
+
+ _slen = _sea_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].sea_category()) &&
+ ( info[p].sea_category()) <= _keys[1] ?
+ ( info[p].sea_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _sea_syllable_machine_trans_targs[_trans];
+
+ if ( _sea_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _sea_syllable_machine_trans_actions[_trans] ) {
+ case 2:
+#line 1 "NONE"
+ {te = p+1;}
+ break;
+ case 6:
+#line 63 "hb-ot-shape-complex-sea-machine.rl"
+ {te = p+1;{ found_syllable (non_sea_cluster); }}
+ break;
+ case 7:
+#line 61 "hb-ot-shape-complex-sea-machine.rl"
+ {te = p;p--;{ found_syllable (consonant_syllable); }}
+ break;
+ case 8:
+#line 62 "hb-ot-shape-complex-sea-machine.rl"
+ {te = p;p--;{ found_syllable (broken_cluster); }}
+ break;
+ case 9:
+#line 63 "hb-ot-shape-complex-sea-machine.rl"
+ {te = p;p--;{ found_syllable (non_sea_cluster); }}
+ break;
+ case 1:
+#line 61 "hb-ot-shape-complex-sea-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
+ break;
+ case 3:
+#line 62 "hb-ot-shape-complex-sea-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
+ break;
+#line 194 "hb-ot-shape-complex-sea-machine.hh"
+ }
+
+_again:
+ switch ( _sea_syllable_machine_to_state_actions[cs] ) {
+ case 4:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 203 "hb-ot-shape-complex-sea-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _sea_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _sea_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 97 "hb-ot-shape-complex-sea-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
new file mode 100644
index 0000000000..9c0c303e3d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
@@ -0,0 +1,384 @@
+/*
+ * Copyright © 2011,2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+
+/* buffer var allocations */
+#define sea_category() complex_var_u8_0() /* indic_category_t */
+#define sea_position() complex_var_u8_1() /* indic_position_t */
+
+
+/*
+ * South-East Asian shaper.
+ * Loosely based on the Myanmar spec / shaper.
+ * There is no OpenType spec for this.
+ */
+
+static const hb_tag_t
+basic_features[] =
+{
+ /*
+ * Basic features.
+ * These features are applied in order, one at a time, after initial_reordering.
+ */
+ HB_TAG('p','r','e','f'),
+ HB_TAG('a','b','v','f'),
+ HB_TAG('b','l','w','f'),
+ HB_TAG('p','s','t','f'),
+};
+static const hb_tag_t
+other_features[] =
+{
+ /*
+ * Other features.
+ * These features are applied all at once, after final_reordering.
+ */
+ HB_TAG('p','r','e','s'),
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('p','s','t','s'),
+ /* Positioning features, though we don't care about the types. */
+ HB_TAG('d','i','s','t'),
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
+collect_features_sea (hb_ot_shape_planner_t *plan)
+{
+ hb_ot_map_builder_t *map = &plan->map;
+
+ /* Do this before any lookups have been applied. */
+ map->add_gsub_pause (setup_syllables);
+
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+ /* The Indic specs do not require ccmp, but we apply it here since if
+ * there is a use of it, it's typically at the beginning. */
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+
+ map->add_gsub_pause (initial_reordering);
+ for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
+ {
+ map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+ map->add_gsub_pause (NULL);
+ }
+ map->add_gsub_pause (final_reordering);
+ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+ map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+}
+
+static void
+override_features_sea (hb_ot_shape_planner_t *plan)
+{
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+}
+
+
+enum syllable_type_t {
+ consonant_syllable,
+ broken_cluster,
+ non_sea_cluster,
+};
+
+#include "hb-ot-shape-complex-sea-machine.hh"
+
+
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum sea_category_t {
+// OT_C = 1,
+ OT_GB = 12, /* Generic Base XXX DOTTED CIRCLE only for now */
+// OT_H = 4, /* Halant */
+ OT_IV = 2, /* Independent Vowel */
+ OT_MR = 22, /* Medial Ra */
+// OT_CM = 17, /* Consonant Medial */
+ OT_VAbv = 26,
+ OT_VBlw = 27,
+ OT_VPre = 28,
+ OT_VPst = 29,
+ OT_T = 3, /* Tone Marks */
+// OT_A = 10, /* Anusvara */
+};
+
+static inline void
+set_sea_properties (hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+ indic_category_t cat = (indic_category_t) (type & 0x7F);
+ indic_position_t pos = (indic_position_t) (type >> 8);
+
+ /* Medial Ra */
+ if (u == 0x1A55 || u == 0xAA34)
+ cat = (indic_category_t) OT_MR;
+
+ if (cat == OT_M)
+ {
+ switch ((int) pos)
+ {
+ case POS_PRE_C: cat = (indic_category_t) OT_VPre; break;
+ case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break;
+ case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break;
+ case POS_POST_C: cat = (indic_category_t) OT_VPst; break;
+ }
+ }
+
+ info.sea_category() = (sea_category_t) cat;
+ info.sea_position() = pos;
+}
+
+
+static void
+setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, sea_category);
+ HB_BUFFER_ALLOCATE_VAR (buffer, sea_position);
+
+ /* We cannot setup masks here. We save information about characters
+ * and setup masks later on in a pause-callback. */
+
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ set_sea_properties (buffer->info[i]);
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ find_syllables (buffer);
+}
+
+static int
+compare_sea_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+ int a = pa->sea_position();
+ int b = pb->sea_position();
+
+ return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+static void
+initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int base = start;
+
+ /* Reorder! */
+ unsigned int i = start;
+ for (; i < base; i++)
+ info[i].sea_position() = POS_PRE_C;
+ if (i < end)
+ {
+ info[i].sea_position() = POS_BASE_C;
+ i++;
+ }
+ for (; i < end; i++)
+ {
+ if (info[i].sea_category() == OT_MR) /* Pre-base reordering */
+ {
+ info[i].sea_position() = POS_PRE_C;
+ continue;
+ }
+ if (info[i].sea_category() == OT_VPre) /* Left matra */
+ {
+ info[i].sea_position() = POS_PRE_M;
+ continue;
+ }
+
+ info[i].sea_position() = POS_AFTER_MAIN;
+ }
+
+ buffer->merge_clusters (start, end);
+ /* Sit tight, rock 'n roll! */
+ hb_bubble_sort (info + start, end - start, compare_sea_order);
+}
+
+static void
+initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ /* We already inserted dotted-circles, so just call the consonant_syllable. */
+ initial_reordering_consonant_syllable (plan, face, buffer, start, end);
+}
+
+static void
+initial_reordering_non_sea_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ hb_buffer_t *buffer HB_UNUSED,
+ unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
+{
+ /* Nothing to do right now. If we ever switch to using the output
+ * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+
+static void
+initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+ switch (syllable_type) {
+ case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
+ case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
+ case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
+ }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ /* Note: This loop is extra overhead, but should not be measurable. */
+ bool has_broken_syllables = false;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
+ has_broken_syllables = true;
+ break;
+ }
+ if (likely (!has_broken_syllables))
+ return;
+
+
+ hb_codepoint_t dottedcircle_glyph;
+ if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
+ return;
+
+ hb_glyph_info_t dottedcircle = {0};
+ dottedcircle.codepoint = 0x25CC;
+ set_sea_properties (dottedcircle);
+ dottedcircle.codepoint = dottedcircle_glyph;
+
+ buffer->clear_output ();
+
+ buffer->idx = 0;
+ unsigned int last_syllable = 0;
+ while (buffer->idx < buffer->len)
+ {
+ unsigned int syllable = buffer->cur().syllable();
+ syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+ if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+ {
+ last_syllable = syllable;
+
+ hb_glyph_info_t info = dottedcircle;
+ info.cluster = buffer->cur().cluster;
+ info.mask = buffer->cur().mask;
+ info.syllable() = buffer->cur().syllable();
+
+ buffer->output_info (info);
+ }
+ else
+ buffer->next_glyph ();
+ }
+
+ buffer->swap_buffers ();
+}
+
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ insert_dotted_circles (plan, font, buffer);
+
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+ unsigned int last = 0;
+ unsigned int last_syllable = info[0].syllable();
+ for (unsigned int i = 1; i < count; i++)
+ if (last_syllable != info[i].syllable()) {
+ initial_reordering_syllable (plan, font->face, buffer, last, i);
+ last = i;
+ last_syllable = info[last].syllable();
+ }
+ initial_reordering_syllable (plan, font->face, buffer, last, count);
+}
+
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+
+ /* Zero syllables now... */
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, sea_category);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, sea_position);
+}
+
+
+static hb_ot_shape_normalization_mode_t
+normalization_preference_sea (const hb_segment_properties_t *props HB_UNUSED)
+{
+ return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea =
+{
+ "sea",
+ collect_features_sea,
+ override_features_sea,
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ NULL, /* preprocess_text */
+ normalization_preference_sea,
+ NULL, /* decompose */
+ NULL, /* compose */
+ setup_masks_sea,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+ false, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
new file mode 100644
index 0000000000..45945339d6
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
@@ -0,0 +1,378 @@
+/*
+ * Copyright © 2010,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+/* Thai / Lao shaper */
+
+
+/* PUA shaping */
+
+
+enum thai_consonant_type_t
+{
+ NC,
+ AC,
+ RC,
+ DC,
+ NOT_CONSONANT,
+ NUM_CONSONANT_TYPES = NOT_CONSONANT
+};
+
+static thai_consonant_type_t
+get_consonant_type (hb_codepoint_t u)
+{
+ if (u == 0x0E1B || u == 0x0E1D || u == 0x0E1F/* || u == 0x0E2C*/)
+ return AC;
+ if (u == 0x0E0D || u == 0x0E10)
+ return RC;
+ if (u == 0x0E0E || u == 0x0E0F)
+ return DC;
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E01, 0x0E2E))
+ return NC;
+ return NOT_CONSONANT;
+}
+
+
+enum thai_mark_type_t
+{
+ AV,
+ BV,
+ T,
+ NOT_MARK,
+ NUM_MARK_TYPES = NOT_MARK
+};
+
+static thai_mark_type_t
+get_mark_type (hb_codepoint_t u)
+{
+ if (u == 0x0E31 || hb_in_range<hb_codepoint_t> (u, 0x0E34, 0x0E37) ||
+ u == 0x0E47 || hb_in_range<hb_codepoint_t> (u, 0x0E4D, 0x0E4E))
+ return AV;
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E38, 0x0E3A))
+ return BV;
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E48, 0x0E4C))
+ return T;
+ return NOT_MARK;
+}
+
+
+enum thai_action_t
+{
+ NOP,
+ SD, /* Shift combining-mark down */
+ SL, /* Shift combining-mark left */
+ SDL, /* Shift combining-mark down-left */
+ RD /* Remove descender from base */
+};
+
+static hb_codepoint_t
+thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
+{
+ struct thai_pua_mapping_t {
+ hb_codepoint_t u;
+ hb_codepoint_t win_pua;
+ hb_codepoint_t mac_pua;
+ } const *pua_mappings = NULL;
+ static const thai_pua_mapping_t SD_mappings[] = {
+ {0x0E48, 0xF70A, 0xF88B}, /* MAI EK */
+ {0x0E49, 0xF70B, 0xF88E}, /* MAI THO */
+ {0x0E4A, 0xF70C, 0xF891}, /* MAI TRI */
+ {0x0E4B, 0xF70D, 0xF894}, /* MAI CHATTAWA */
+ {0x0E4C, 0xF70E, 0xF897}, /* THANTHAKHAT */
+ {0x0E38, 0xF718, 0xF89B}, /* SARA U */
+ {0x0E39, 0xF719, 0xF89C}, /* SARA UU */
+ {0x0E3A, 0xF71A, 0xF89D}, /* PHINTHU */
+ {0x0000, 0x0000, 0x0000}
+ };
+ static const thai_pua_mapping_t SDL_mappings[] = {
+ {0x0E48, 0xF705, 0xF88C}, /* MAI EK */
+ {0x0E49, 0xF706, 0xF88F}, /* MAI THO */
+ {0x0E4A, 0xF707, 0xF892}, /* MAI TRI */
+ {0x0E4B, 0xF708, 0xF895}, /* MAI CHATTAWA */
+ {0x0E4C, 0xF709, 0xF898}, /* THANTHAKHAT */
+ {0x0000, 0x0000, 0x0000}
+ };
+ static const thai_pua_mapping_t SL_mappings[] = {
+ {0x0E48, 0xF713, 0xF88A}, /* MAI EK */
+ {0x0E49, 0xF714, 0xF88D}, /* MAI THO */
+ {0x0E4A, 0xF715, 0xF890}, /* MAI TRI */
+ {0x0E4B, 0xF716, 0xF893}, /* MAI CHATTAWA */
+ {0x0E4C, 0xF717, 0xF896}, /* THANTHAKHAT */
+ {0x0E31, 0xF710, 0xF884}, /* MAI HAN-AKAT */
+ {0x0E34, 0xF701, 0xF885}, /* SARA I */
+ {0x0E35, 0xF702, 0xF886}, /* SARA II */
+ {0x0E36, 0xF703, 0xF887}, /* SARA UE */
+ {0x0E37, 0xF704, 0xF888}, /* SARA UEE */
+ {0x0E47, 0xF712, 0xF889}, /* MAITAIKHU */
+ {0x0E4D, 0xF711, 0xF899}, /* NIKHAHIT */
+ {0x0000, 0x0000, 0x0000}
+ };
+ static const thai_pua_mapping_t RD_mappings[] = {
+ {0x0E0D, 0xF70F, 0xF89A}, /* YO YING */
+ {0x0E10, 0xF700, 0xF89E}, /* THO THAN */
+ {0x0000, 0x0000, 0x0000}
+ };
+
+ switch (action) {
+ default: assert (false); /* Fallthrough */
+ case NOP: return u;
+ case SD: pua_mappings = SD_mappings; break;
+ case SDL: pua_mappings = SDL_mappings; break;
+ case SL: pua_mappings = SL_mappings; break;
+ case RD: pua_mappings = RD_mappings; break;
+ }
+ for (; pua_mappings->u; pua_mappings++)
+ if (pua_mappings->u == u)
+ {
+ hb_codepoint_t glyph;
+ if (hb_font_get_glyph (font, pua_mappings->win_pua, 0, &glyph))
+ return pua_mappings->win_pua;
+ if (hb_font_get_glyph (font, pua_mappings->mac_pua, 0, &glyph))
+ return pua_mappings->mac_pua;
+ break;
+ }
+ return u;
+}
+
+
+static enum thai_above_state_t
+{ /* Cluster above looks like: */
+ T0, /* ⣤ */
+ T1, /* ⣼ */
+ T2, /* ⣾ */
+ T3, /* ⣿ */
+ NUM_ABOVE_STATES
+} thai_above_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
+{
+ T0, /* NC */
+ T1, /* AC */
+ T0, /* RC */
+ T0, /* DC */
+ T3, /* NOT_CONSONANT */
+};
+
+static const struct thai_above_state_machine_edge_t {
+ thai_action_t action;
+ thai_above_state_t next_state;
+} thai_above_state_machine[NUM_ABOVE_STATES][NUM_MARK_TYPES] =
+{ /*AV*/ /*BV*/ /*T*/
+/*T0*/ {{NOP,T3}, {NOP,T0}, {SD, T3}},
+/*T1*/ {{SL, T2}, {NOP,T1}, {SDL,T2}},
+/*T2*/ {{NOP,T3}, {NOP,T2}, {SL, T3}},
+/*T3*/ {{NOP,T3}, {NOP,T3}, {NOP,T3}},
+};
+
+
+static enum thai_below_state_t
+{
+ B0, /* No descender */
+ B1, /* Removable descender */
+ B2, /* Strict descender */
+ NUM_BELOW_STATES
+} thai_below_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
+{
+ B0, /* NC */
+ B0, /* AC */
+ B1, /* RC */
+ B2, /* DC */
+ B2, /* NOT_CONSONANT */
+};
+
+static const struct thai_below_state_machine_edge_t {
+ thai_action_t action;
+ thai_below_state_t next_state;
+} thai_below_state_machine[NUM_BELOW_STATES][NUM_MARK_TYPES] =
+{ /*AV*/ /*BV*/ /*T*/
+/*B0*/ {{NOP,B0}, {NOP,B2}, {NOP, B0}},
+/*B1*/ {{NOP,B1}, {RD, B2}, {NOP, B1}},
+/*B2*/ {{NOP,B2}, {SD, B2}, {NOP, B2}},
+};
+
+
+static void
+do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
+{
+ thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
+ thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
+ unsigned int base = 0;
+
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ thai_mark_type_t mt = get_mark_type (info[i].codepoint);
+
+ if (mt == NOT_MARK) {
+ thai_consonant_type_t ct = get_consonant_type (info[i].codepoint);
+ above_state = thai_above_start_state[ct];
+ below_state = thai_below_start_state[ct];
+ base = i;
+ continue;
+ }
+
+ const thai_above_state_machine_edge_t &above_edge = thai_above_state_machine[above_state][mt];
+ const thai_below_state_machine_edge_t &below_edge = thai_below_state_machine[below_state][mt];
+ above_state = above_edge.next_state;
+ below_state = below_edge.next_state;
+
+ /* At least one of the above/below actions is NOP. */
+ thai_action_t action = above_edge.action != NOP ? above_edge.action : below_edge.action;
+
+ if (action == RD)
+ info[base].codepoint = thai_pua_shape (info[base].codepoint, action, font);
+ else
+ info[i].codepoint = thai_pua_shape (info[i].codepoint, action, font);
+ }
+}
+
+
+static void
+preprocess_text_thai (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
+{
+ /* This function implements the shaping logic documented here:
+ *
+ * http://linux.thai.net/~thep/th-otf/shaping.html
+ *
+ * The first shaping rule listed there is needed even if the font has Thai
+ * OpenType tables. The rest do fallback positioning based on PUA codepoints.
+ * We implement that only if there exist no Thai GSUB in the font.
+ */
+
+ /* The following is NOT specified in the MS OT Thai spec, however, it seems
+ * to be what Uniscribe and other engines implement. According to Eric Muller:
+ *
+ * When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
+ * NIKHAHIT backwards over any tone mark (0E48-0E4B).
+ *
+ * <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32>
+ *
+ * This reordering is legit only when the NIKHAHIT comes from a SARA AM, not
+ * when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably
+ * not what a user wanted, but the rendering is nevertheless nikhahit above
+ * chattawa.
+ *
+ * Same for Lao.
+ *
+ * Note:
+ *
+ * Uniscribe also does some below-marks reordering. Namely, it positions U+0E3A
+ * after U+0E38 and U+0E39. We do that by modifying the ccc for U+0E3A.
+ * See unicode->modified_combining_class (). Lao does NOT have a U+0E3A
+ * equivalent.
+ */
+
+
+ /*
+ * Here are the characters of significance:
+ *
+ * Thai Lao
+ * SARA AM: U+0E33 U+0EB3
+ * SARA AA: U+0E32 U+0EB2
+ * Nikhahit: U+0E4D U+0ECD
+ *
+ * Testing shows that Uniscribe reorder the following marks:
+ * Thai: <0E31,0E34..0E37,0E47..0E4E>
+ * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE>
+ *
+ * Note how the Lao versions are the same as Thai + 0x80.
+ */
+
+ /* We only get one script at a time, so a script-agnostic implementation
+ * is adequate here. */
+#define IS_SARA_AM(x) (((x) & ~0x0080) == 0x0E33)
+#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0xE33 + 0xE4D)
+#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
+#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080, 0x0E34, 0x0E37, 0x0E47, 0x0E4E, 0x0E31, 0x0E31))
+
+ buffer->clear_output ();
+ unsigned int count = buffer->len;
+ for (buffer->idx = 0; buffer->idx < count;)
+ {
+ hb_codepoint_t u = buffer->cur().codepoint;
+ if (likely (!IS_SARA_AM (u))) {
+ buffer->next_glyph ();
+ continue;
+ }
+
+ /* Is SARA AM. Decompose and reorder. */
+ hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
+ hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
+ buffer->replace_glyphs (1, 2, decomposed);
+ if (unlikely (buffer->in_error))
+ return;
+
+ /* Ok, let's see... */
+ unsigned int end = buffer->out_len;
+ unsigned int start = end - 2;
+ while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
+ start--;
+
+ if (start + 2 < end)
+ {
+ /* Move Nikhahit (end-2) to the beginning */
+ buffer->merge_out_clusters (start, end);
+ hb_glyph_info_t t = buffer->out_info[end - 2];
+ memmove (buffer->out_info + start + 1,
+ buffer->out_info + start,
+ sizeof (buffer->out_info[0]) * (end - start - 2));
+ buffer->out_info[start] = t;
+ }
+ else
+ {
+ /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the
+ * previous cluster. */
+ if (start)
+ buffer->merge_out_clusters (start - 1, end);
+ }
+ }
+ buffer->swap_buffers ();
+
+ /* If font has Thai GSUB, we are done. */
+ if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
+ do_thai_pua_shaping (plan, buffer, font);
+}
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
+{
+ "thai",
+ NULL, /* collect_features */
+ NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ preprocess_text_thai,
+ NULL, /* normalization_preference */
+ NULL, /* decompose */
+ NULL, /* compose */
+ NULL, /* setup_masks */
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+ false,/* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh
new file mode 100644
index 0000000000..ec653513f1
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_FALLBACK_PRIVATE_HH
+#define HB_OT_SHAPE_FALLBACK_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-shape-private.hh"
+
+
+HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+#endif /* HB_OT_SHAPE_FALLBACK_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
new file mode 100644
index 0000000000..284d030d5f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -0,0 +1,456 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-fallback-private.hh"
+#include "hb-ot-layout-gsubgpos-private.hh"
+
+static unsigned int
+recategorize_combining_class (hb_codepoint_t u,
+ unsigned int klass)
+{
+ if (klass >= 200)
+ return klass;
+
+ /* Thai / Lao need some per-character work. */
+ if ((u & ~0xFF) == 0x0E00)
+ {
+ if (unlikely (klass == 0))
+ {
+ switch (u)
+ {
+ case 0x0E31:
+ case 0x0E34:
+ case 0x0E35:
+ case 0x0E36:
+ case 0x0E37:
+ case 0x0E47:
+ case 0x0E4C:
+ case 0x0E4D:
+ case 0x0E4E:
+ klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
+ break;
+
+ case 0x0EB1:
+ case 0x0EB4:
+ case 0x0EB5:
+ case 0x0EB6:
+ case 0x0EB7:
+ case 0x0EBB:
+ case 0x0ECC:
+ case 0x0ECD:
+ klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
+ break;
+
+ case 0x0EBC:
+ klass = HB_UNICODE_COMBINING_CLASS_BELOW;
+ break;
+ }
+ } else {
+ /* Thai virama is below-right */
+ if (u == 0x0E3A)
+ klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
+ }
+ }
+
+ switch (klass)
+ {
+
+ /* Hebrew */
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC10: /* sheva */
+ case HB_MODIFIED_COMBINING_CLASS_CCC11: /* hataf segol */
+ case HB_MODIFIED_COMBINING_CLASS_CCC12: /* hataf patah */
+ case HB_MODIFIED_COMBINING_CLASS_CCC13: /* hataf qamats */
+ case HB_MODIFIED_COMBINING_CLASS_CCC14: /* hiriq */
+ case HB_MODIFIED_COMBINING_CLASS_CCC15: /* tsere */
+ case HB_MODIFIED_COMBINING_CLASS_CCC16: /* segol */
+ case HB_MODIFIED_COMBINING_CLASS_CCC17: /* patah */
+ case HB_MODIFIED_COMBINING_CLASS_CCC18: /* qamats */
+ case HB_MODIFIED_COMBINING_CLASS_CCC20: /* qubuts */
+ case HB_MODIFIED_COMBINING_CLASS_CCC22: /* meteg */
+ return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC23: /* rafe */
+ return HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC24: /* shin dot */
+ return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC25: /* sin dot */
+ case HB_MODIFIED_COMBINING_CLASS_CCC19: /* holam */
+ return HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC26: /* point varika */
+ return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC21: /* dagesh */
+ break;
+
+
+ /* Arabic and Syriac */
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC27: /* fathatan */
+ case HB_MODIFIED_COMBINING_CLASS_CCC28: /* dammatan */
+ case HB_MODIFIED_COMBINING_CLASS_CCC30: /* fatha */
+ case HB_MODIFIED_COMBINING_CLASS_CCC31: /* damma */
+ case HB_MODIFIED_COMBINING_CLASS_CCC33: /* shadda */
+ case HB_MODIFIED_COMBINING_CLASS_CCC34: /* sukun */
+ case HB_MODIFIED_COMBINING_CLASS_CCC35: /* superscript alef */
+ case HB_MODIFIED_COMBINING_CLASS_CCC36: /* superscript alaph */
+ return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC29: /* kasratan */
+ case HB_MODIFIED_COMBINING_CLASS_CCC32: /* kasra */
+ return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+
+ /* Thai */
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC103: /* sara u / sara uu */
+ return HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC107: /* mai */
+ return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
+
+
+ /* Lao */
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC118: /* sign u / sign uu */
+ return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC122: /* mai */
+ return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+
+ /* Tibetan */
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC129: /* sign aa */
+ return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC130: /* sign i*/
+ return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+ case HB_MODIFIED_COMBINING_CLASS_CCC132: /* sign u */
+ return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+ }
+
+ return klass;
+}
+
+void
+_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
+ unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
+ combining_class = recategorize_combining_class (buffer->info[i].codepoint, combining_class);
+ _hb_glyph_info_set_modified_combining_class (&buffer->info[i], combining_class);
+ }
+}
+
+
+static void
+zero_mark_advances (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end)
+{
+ for (unsigned int i = start; i < end; i++)
+ if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ {
+ buffer->pos[i].x_advance = 0;
+ buffer->pos[i].y_advance = 0;
+ }
+}
+
+static inline void
+position_mark (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ hb_glyph_extents_t &base_extents,
+ unsigned int i,
+ unsigned int combining_class)
+{
+ hb_glyph_extents_t mark_extents;
+ if (!font->get_glyph_extents (buffer->info[i].codepoint,
+ &mark_extents))
+ return;
+
+ hb_position_t y_gap = font->y_scale / 16;
+
+ hb_glyph_position_t &pos = buffer->pos[i];
+ pos.x_offset = pos.y_offset = 0;
+
+
+ /* We dont position LEFT and RIGHT marks. */
+
+ /* X positioning */
+ switch (combining_class)
+ {
+ case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW:
+ case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
+ if (buffer->props.direction == HB_DIRECTION_LTR) {
+ pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
+ break;
+ } else if (buffer->props.direction == HB_DIRECTION_RTL) {
+ pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
+ break;
+ }
+ /* Fall through */
+
+ default:
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
+ case HB_UNICODE_COMBINING_CLASS_BELOW:
+ case HB_UNICODE_COMBINING_CLASS_ABOVE:
+ /* Center align. */
+ pos.x_offset += base_extents.x_bearing + (base_extents.width - mark_extents.width) / 2 - mark_extents.x_bearing;
+ break;
+
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
+ case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT:
+ case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT:
+ /* Left align. */
+ pos.x_offset += base_extents.x_bearing - mark_extents.x_bearing;
+ break;
+
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
+ case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT:
+ case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT:
+ /* Right align. */
+ pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width - mark_extents.x_bearing;
+ break;
+ }
+
+ /* Y positioning */
+ switch (combining_class)
+ {
+ case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW:
+ case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT:
+ case HB_UNICODE_COMBINING_CLASS_BELOW:
+ case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT:
+ /* Add gap, fall-through. */
+ base_extents.height -= y_gap;
+
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
+ pos.y_offset += base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+ base_extents.height += mark_extents.height;
+ break;
+
+ case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
+ case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT:
+ case HB_UNICODE_COMBINING_CLASS_ABOVE:
+ case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT:
+ /* Add gap, fall-through. */
+ base_extents.y_bearing += y_gap;
+ base_extents.height -= y_gap;
+
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
+ case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
+ pos.y_offset += base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+ base_extents.y_bearing -= mark_extents.height;
+ base_extents.height += mark_extents.height;
+ break;
+ }
+}
+
+static inline void
+position_around_base (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ unsigned int base,
+ unsigned int end)
+{
+ hb_direction_t horiz_dir = HB_DIRECTION_INVALID;
+ hb_glyph_extents_t base_extents;
+ if (!font->get_glyph_extents (buffer->info[base].codepoint,
+ &base_extents))
+ {
+ /* If extents don't work, zero marks and go home. */
+ zero_mark_advances (buffer, base + 1, end);
+ return;
+ }
+ base_extents.x_bearing += buffer->pos[base].x_offset;
+ base_extents.y_bearing += buffer->pos[base].y_offset;
+
+ unsigned int lig_id = get_lig_id (buffer->info[base]);
+ unsigned int num_lig_components = get_lig_num_comps (buffer->info[base]);
+
+ hb_position_t x_offset = 0, y_offset = 0;
+ if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
+ x_offset -= buffer->pos[base].x_advance;
+ y_offset -= buffer->pos[base].y_advance;
+ }
+
+ hb_glyph_extents_t component_extents = base_extents;
+ unsigned int last_lig_component = (unsigned int) -1;
+ unsigned int last_combining_class = 255;
+ hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
+ {
+ if (num_lig_components > 1) {
+ unsigned int this_lig_id = get_lig_id (buffer->info[i]);
+ unsigned int this_lig_component = get_lig_comp (buffer->info[i]) - 1;
+ /* Conditions for attaching to the last component. */
+ if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
+ this_lig_component = num_lig_components - 1;
+ if (last_lig_component != this_lig_component)
+ {
+ last_lig_component = this_lig_component;
+ last_combining_class = 255;
+ component_extents = base_extents;
+ if (unlikely (horiz_dir == HB_DIRECTION_INVALID)) {
+ if (HB_DIRECTION_IS_HORIZONTAL (plan->props.direction))
+ horiz_dir = plan->props.direction;
+ else
+ horiz_dir = hb_script_get_horizontal_direction (plan->props.script);
+ }
+ if (horiz_dir == HB_DIRECTION_LTR)
+ component_extents.x_bearing += (this_lig_component * component_extents.width) / num_lig_components;
+ else
+ component_extents.x_bearing += ((num_lig_components - 1 - this_lig_component) * component_extents.width) / num_lig_components;
+ component_extents.width /= num_lig_components;
+ }
+ }
+
+ unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
+ if (last_combining_class != this_combining_class)
+ {
+ last_combining_class = this_combining_class;
+ cluster_extents = component_extents;
+ }
+
+ position_mark (plan, font, buffer, cluster_extents, i, this_combining_class);
+
+ buffer->pos[i].x_advance = 0;
+ buffer->pos[i].y_advance = 0;
+ buffer->pos[i].x_offset += x_offset;
+ buffer->pos[i].y_offset += y_offset;
+
+ } else {
+ if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
+ x_offset -= buffer->pos[i].x_advance;
+ y_offset -= buffer->pos[i].y_advance;
+ } else {
+ x_offset += buffer->pos[i].x_advance;
+ y_offset += buffer->pos[i].y_advance;
+ }
+ }
+}
+
+static inline void
+position_cluster (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end)
+{
+ if (end - start < 2)
+ return;
+
+ /* Find the base glyph */
+ for (unsigned int i = start; i < end; i++)
+ if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
+ {
+ /* Find mark glyphs */
+ unsigned int j;
+ for (j = i + 1; j < end; j++)
+ if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[j])))
+ break;
+
+ position_around_base (plan, font, buffer, i, j);
+
+ i = j - 1;
+ }
+}
+
+void
+_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ unsigned int start = 0;
+ unsigned int last_cluster = buffer->info[0].cluster;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 1; i < count; i++)
+ if (buffer->info[i].cluster != last_cluster) {
+ position_cluster (plan, font, buffer, start, i);
+ start = i;
+ last_cluster = buffer->info[i].cluster;
+ }
+ position_cluster (plan, font, buffer, start, count);
+}
+
+
+/* Performs old-style TrueType kerning. */
+void
+_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ hb_mask_t kern_mask = plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
+ HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
+
+ OT::hb_apply_context_t c (1, font, buffer);
+ c.set_lookup_mask (kern_mask);
+ c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
+
+ for (buffer->idx = 0; buffer->idx < count;)
+ {
+ OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, buffer->idx, 1);
+ if (!skippy_iter.next ())
+ {
+ buffer->idx++;
+ continue;
+ }
+
+ hb_position_t x_kern, y_kern, kern1, kern2;
+ font->get_glyph_kerning_for_direction (buffer->info[buffer->idx].codepoint,
+ buffer->info[skippy_iter.idx].codepoint,
+ buffer->props.direction,
+ &x_kern, &y_kern);
+
+ kern1 = x_kern >> 1;
+ kern2 = x_kern - kern1;
+ buffer->pos[buffer->idx].x_advance += kern1;
+ buffer->pos[skippy_iter.idx].x_advance += kern2;
+ buffer->pos[skippy_iter.idx].x_offset += kern2;
+
+ kern1 = y_kern >> 1;
+ kern2 = y_kern - kern1;
+ buffer->pos[buffer->idx].y_advance += kern1;
+ buffer->pos[skippy_iter.idx].y_advance += kern2;
+ buffer->pos[skippy_iter.idx].y_offset += kern2;
+
+ buffer->idx = skippy_iter.idx;
+ }
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
new file mode 100644
index 0000000000..085d48511d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_NORMALIZE_PRIVATE_HH
+#define HB_OT_SHAPE_NORMALIZE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-font.h"
+#include "hb-buffer.h"
+
+/* buffer var allocations, used during the normalization process */
+#define glyph_index() var1.u32
+
+struct hb_ot_shape_plan_t;
+
+enum hb_ot_shape_normalization_mode_t {
+ HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */
+
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS
+};
+
+HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,
+ hb_buffer_t *buffer,
+ hb_font_t *font);
+
+
+struct hb_ot_shape_normalize_context_t
+{
+ const hb_ot_shape_plan_t *plan;
+ hb_buffer_t *buffer;
+ hb_font_t *font;
+ hb_unicode_funcs_t *unicode;
+ bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b);
+ bool (*compose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab);
+};
+
+
+#endif /* HB_OT_SHAPE_NORMALIZE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
new file mode 100644
index 0000000000..3fee809cf9
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -0,0 +1,408 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-normalize-private.hh"
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh"
+
+
+/*
+ * HIGHLEVEL DESIGN:
+ *
+ * This file exports one main function: _hb_ot_shape_normalize().
+ *
+ * This function closely reflects the Unicode Normalization Algorithm,
+ * yet it's different.
+ *
+ * Each shaper specifies whether it prefers decomposed (NFD) or composed (NFC).
+ * The logic however tries to use whatever the font can support.
+ *
+ * In general what happens is that: each grapheme is decomposed in a chain
+ * of 1:2 decompositions, marks reordered, and then recomposed if desired,
+ * so far it's like Unicode Normalization. However, the decomposition and
+ * recomposition only happens if the font supports the resulting characters.
+ *
+ * The goals are:
+ *
+ * - Try to render all canonically equivalent strings similarly. To really
+ * achieve this we have to always do the full decomposition and then
+ * selectively recompose from there. It's kinda too expensive though, so
+ * we skip some cases. For example, if composed is desired, we simply
+ * don't touch 1-character clusters that are supported by the font, even
+ * though their NFC may be different.
+ *
+ * - When a font has a precomposed character for a sequence but the 'ccmp'
+ * feature in the font is not adequate, use the precomposed character
+ * which typically has better mark positioning.
+ *
+ * - When a font does not support a combining mark, but supports it precomposed
+ * with previous base, use that. This needs the itemizer to have this
+ * knowledge too. We need to provide assistance to the itemizer.
+ *
+ * - When a font does not support a character but supports its decomposition,
+ * well, use the decomposition (preferring the canonical decomposition, but
+ * falling back to the compatibility decomposition if necessary). The
+ * compatibility decomposition is really nice to have, for characters like
+ * ellipsis, or various-sized space characters.
+ *
+ * - The complex shapers can customize the compose and decompose functions to
+ * offload some of their requirements to the normalizer. For example, the
+ * Indic shaper may want to disallow recomposing of two matras.
+ *
+ * - We try compatibility decomposition if decomposing through canonical
+ * decomposition alone failed to find a sequence that the font supports.
+ * We don't try compatibility decomposition recursively during the canonical
+ * decomposition phase. This has minimal impact. There are only a handful
+ * of Greek letter that have canonical decompositions that include characters
+ * with compatibility decomposition. Those can be found using this command:
+ *
+ * egrep "`echo -n ';('; grep ';<' UnicodeData.txt | cut -d';' -f1 | tr '\n' '|'; echo ') '`" UnicodeData.txt
+ */
+
+static bool
+decompose_unicode (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b)
+{
+ return c->unicode->decompose (ab, a, b);
+}
+
+static bool
+compose_unicode (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
+{
+ return c->unicode->compose (a, b, ab);
+}
+
+static inline void
+set_glyph (hb_glyph_info_t &info, hb_font_t *font)
+{
+ font->get_glyph (info.codepoint, 0, &info.glyph_index());
+}
+
+static inline void
+output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
+{
+ buffer->cur().glyph_index() = glyph;
+ buffer->output_glyph (unichar);
+ _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode);
+}
+
+static inline void
+next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
+{
+ buffer->cur().glyph_index() = glyph;
+ buffer->next_glyph ();
+}
+
+static inline void
+skip_char (hb_buffer_t *buffer)
+{
+ buffer->skip_glyph ();
+}
+
+/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
+static inline unsigned int
+decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
+{
+ hb_codepoint_t a, b, a_glyph, b_glyph;
+
+ if (!c->decompose (c, ab, &a, &b) ||
+ (b && !c->font->get_glyph (b, 0, &b_glyph)))
+ return 0;
+
+ bool has_a = c->font->get_glyph (a, 0, &a_glyph);
+ if (shortest && has_a) {
+ /* Output a and b */
+ output_char (c->buffer, a, a_glyph);
+ if (likely (b)) {
+ output_char (c->buffer, b, b_glyph);
+ return 2;
+ }
+ return 1;
+ }
+
+ unsigned int ret;
+ if ((ret = decompose (c, shortest, a))) {
+ if (b) {
+ output_char (c->buffer, b, b_glyph);
+ return ret + 1;
+ }
+ return ret;
+ }
+
+ if (has_a) {
+ output_char (c->buffer, a, a_glyph);
+ if (likely (b)) {
+ output_char (c->buffer, b, b_glyph);
+ return 2;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
+static inline unsigned int
+decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t u)
+{
+ unsigned int len, i;
+ hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
+ hb_codepoint_t glyphs[HB_UNICODE_MAX_DECOMPOSITION_LEN];
+
+ len = c->buffer->unicode->decompose_compatibility (u, decomposed);
+ if (!len)
+ return 0;
+
+ for (i = 0; i < len; i++)
+ if (!c->font->get_glyph (decomposed[i], 0, &glyphs[i]))
+ return 0;
+
+ for (i = 0; i < len; i++)
+ output_char (c->buffer, decomposed[i], glyphs[i]);
+
+ return len;
+}
+
+static inline void
+decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest)
+{
+ hb_buffer_t * const buffer = c->buffer;
+ hb_codepoint_t glyph;
+
+ /* Kind of a cute waterfall here... */
+ if (shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
+ next_char (buffer, glyph);
+ else if (decompose (c, shortest, buffer->cur().codepoint))
+ skip_char (buffer);
+ else if (!shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
+ next_char (buffer, glyph);
+ else if (decompose_compatibility (c, buffer->cur().codepoint))
+ skip_char (buffer);
+ else
+ next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
+}
+
+static inline void
+handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
+{
+ hb_buffer_t * const buffer = c->buffer;
+ for (; buffer->idx < end - 1;) {
+ if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
+ /* The next two lines are some ugly lines... But work. */
+ if (c->font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
+ {
+ buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
+ }
+ else
+ {
+ /* Just pass on the two characters separately, let GSUB do its magic. */
+ set_glyph (buffer->cur(), c->font);
+ buffer->next_glyph ();
+ set_glyph (buffer->cur(), c->font);
+ buffer->next_glyph ();
+ }
+ /* Skip any further variation selectors. */
+ while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
+ {
+ set_glyph (buffer->cur(), c->font);
+ buffer->next_glyph ();
+ }
+ } else {
+ set_glyph (buffer->cur(), c->font);
+ buffer->next_glyph ();
+ }
+ }
+ if (likely (buffer->idx < end)) {
+ set_glyph (buffer->cur(), c->font);
+ buffer->next_glyph ();
+ }
+}
+
+static inline void
+decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
+{
+ hb_buffer_t * const buffer = c->buffer;
+ /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
+ for (unsigned int i = buffer->idx; i < end; i++)
+ if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
+ handle_variation_selector_cluster (c, end);
+ return;
+ }
+
+ while (buffer->idx < end)
+ decompose_current_character (c, false);
+}
+
+static inline void
+decompose_cluster (const hb_ot_shape_normalize_context_t *c, bool short_circuit, unsigned int end)
+{
+ if (likely (c->buffer->idx + 1 == end))
+ decompose_current_character (c, short_circuit);
+ else
+ decompose_multi_char_cluster (c, end);
+}
+
+
+static int
+compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+ unsigned int a = _hb_glyph_info_get_modified_combining_class (pa);
+ unsigned int b = _hb_glyph_info_get_modified_combining_class (pb);
+
+ return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+void
+_hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
+{
+ hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference ?
+ plan->shaper->normalization_preference (&buffer->props) :
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT;
+ const hb_ot_shape_normalize_context_t c = {
+ plan,
+ buffer,
+ font,
+ buffer->unicode,
+ plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode,
+ plan->shaper->compose ? plan->shaper->compose : compose_unicode
+ };
+
+ bool short_circuit = mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
+ mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+ unsigned int count;
+
+ /* We do a fairly straightforward yet custom normalization process in three
+ * separate rounds: decompose, reorder, recompose (if desired). Currently
+ * this makes two buffer swaps. We can make it faster by moving the last
+ * two rounds into the inner loop for the first round, but it's more readable
+ * this way. */
+
+
+ /* First round, decompose */
+
+ buffer->clear_output ();
+ count = buffer->len;
+ for (buffer->idx = 0; buffer->idx < count;)
+ {
+ unsigned int end;
+ for (end = buffer->idx + 1; end < count; end++)
+ if (buffer->cur().cluster != buffer->info[end].cluster)
+ break;
+
+ decompose_cluster (&c, short_circuit, end);
+ }
+ buffer->swap_buffers ();
+
+
+ /* Second round, reorder (inplace) */
+
+ count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
+ continue;
+
+ unsigned int end;
+ for (end = i + 1; end < count; end++)
+ if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
+ break;
+
+ /* We are going to do a bubble-sort. Only do this if the
+ * sequence is short. Doing it on long sequences can result
+ * in an O(n^2) DoS. */
+ if (end - i > 10) {
+ i = end;
+ continue;
+ }
+
+ hb_bubble_sort (buffer->info + i, end - i, compare_combining_class);
+
+ i = end;
+ }
+
+
+ if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
+ return;
+
+ /* Third round, recompose */
+
+ /* As noted in the comment earlier, we don't try to combine
+ * ccc=0 chars with their previous Starter. */
+
+ buffer->clear_output ();
+ count = buffer->len;
+ unsigned int starter = 0;
+ buffer->next_glyph ();
+ while (buffer->idx < count)
+ {
+ hb_codepoint_t composed, glyph;
+ if (/* We don't try to compose a non-mark character with it's preceding starter.
+ * This is both an optimization to avoid trying to compose every two neighboring
+ * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul
+ * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
+ HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
+ /* If there's anything between the starter and this char, they should have CCC
+ * smaller than this character's. */
+ (starter == buffer->out_len - 1 ||
+ _hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
+ /* And compose. */
+ c.compose (&c,
+ buffer->out_info[starter].codepoint,
+ buffer->cur().codepoint,
+ &composed) &&
+ /* And the font has glyph for the composite. */
+ font->get_glyph (composed, 0, &glyph))
+ {
+ /* Composes. */
+ buffer->next_glyph (); /* Copy to out-buffer. */
+ if (unlikely (buffer->in_error))
+ return;
+ buffer->merge_out_clusters (starter, buffer->out_len);
+ buffer->out_len--; /* Remove the second composable. */
+ buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */
+ set_glyph (buffer->out_info[starter], font);
+ _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
+
+ continue;
+ }
+
+ /* Blocked, or doesn't compose. */
+ buffer->next_glyph ();
+
+ if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
+ starter = buffer->out_len - 1;
+ }
+ buffer->swap_buffers ();
+
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
new file mode 100644
index 0000000000..817147199f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2010 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_PRIVATE_HH
+#define HB_OT_SHAPE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-map-private.hh"
+#include "hb-ot-layout-private.hh"
+
+
+
+struct hb_ot_shape_plan_t
+{
+ hb_segment_properties_t props;
+ const struct hb_ot_complex_shaper_t *shaper;
+ hb_ot_map_t map;
+ const void *data;
+
+ inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
+ {
+ unsigned int table_index;
+ switch (table_tag) {
+ case HB_OT_TAG_GSUB: table_index = 0; break;
+ case HB_OT_TAG_GPOS: table_index = 1; break;
+ default: return;
+ }
+ map.collect_lookups (table_index, lookups);
+ }
+ inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
+ inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
+
+ void finish (void) { map.finish (); }
+};
+
+struct hb_ot_shape_planner_t
+{
+ /* In the order that they are filled in. */
+ hb_face_t *face;
+ hb_segment_properties_t props;
+ const struct hb_ot_complex_shaper_t *shaper;
+ hb_ot_map_builder_t map;
+
+ hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
+ face (master_plan->face),
+ props (master_plan->props),
+ shaper (NULL),
+ map (face, &props) {}
+ ~hb_ot_shape_planner_t (void) { map.finish (); }
+
+ inline void compile (hb_ot_shape_plan_t &plan)
+ {
+ plan.props = props;
+ plan.shaper = shaper;
+ map.compile (plan.map);
+ }
+
+ private:
+ NO_COPY (hb_ot_shape_planner_t);
+};
+
+
+#endif /* HB_OT_SHAPE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
new file mode 100644
index 0000000000..c23240c80c
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
@@ -0,0 +1,667 @@
+/*
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2010,2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#define HB_SHAPER ot
+#define hb_ot_shaper_face_data_t hb_ot_layout_t
+#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
+#include "hb-shaper-impl-private.hh"
+
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-fallback-private.hh"
+#include "hb-ot-shape-normalize-private.hh"
+
+#include "hb-ot-layout-private.hh"
+#include "hb-set-private.hh"
+
+
+static hb_tag_t common_features[] = {
+ HB_TAG('c','c','m','p'),
+ HB_TAG('l','i','g','a'),
+ HB_TAG('l','o','c','l'),
+ HB_TAG('m','a','r','k'),
+ HB_TAG('m','k','m','k'),
+ HB_TAG('r','l','i','g'),
+};
+
+
+static hb_tag_t horizontal_features[] = {
+ HB_TAG('c','a','l','t'),
+ HB_TAG('c','l','i','g'),
+ HB_TAG('c','u','r','s'),
+ HB_TAG('k','e','r','n'),
+ HB_TAG('r','c','l','t'),
+};
+
+static hb_tag_t vertical_features[] = {
+ HB_TAG('v','e','r','t'),
+};
+
+
+
+static void
+hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ hb_ot_map_builder_t *map = &planner->map;
+
+ switch (props->direction) {
+ case HB_DIRECTION_LTR:
+ map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
+ map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
+ break;
+ case HB_DIRECTION_RTL:
+ map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
+ map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
+ break;
+ case HB_DIRECTION_TTB:
+ case HB_DIRECTION_BTT:
+ case HB_DIRECTION_INVALID:
+ default:
+ break;
+ }
+
+ if (planner->shaper->collect_features)
+ planner->shaper->collect_features (planner);
+
+ for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
+ map->add_global_bool_feature (common_features[i]);
+
+ if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
+ for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
+ map->add_feature (horizontal_features[i], 1, F_GLOBAL |
+ (horizontal_features[i] == HB_TAG('k','e','r','n') ?
+ F_HAS_FALLBACK : F_NONE));
+ else
+ for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++)
+ map->add_feature (vertical_features[i], 1, F_GLOBAL |
+ (vertical_features[i] == HB_TAG('v','k','r','n') ?
+ F_HAS_FALLBACK : F_NONE));
+
+ if (planner->shaper->override_features)
+ planner->shaper->override_features (planner);
+
+ for (unsigned int i = 0; i < num_user_features; i++) {
+ const hb_feature_t *feature = &user_features[i];
+ map->add_feature (feature->tag, feature->value,
+ (feature->start == 0 && feature->end == (unsigned int) -1) ?
+ F_GLOBAL : F_NONE);
+ }
+}
+
+
+/*
+ * shaper face data
+ */
+
+hb_ot_shaper_face_data_t *
+_hb_ot_shaper_face_data_create (hb_face_t *face)
+{
+ return _hb_ot_layout_create (face);
+}
+
+void
+_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
+{
+ _hb_ot_layout_destroy (data);
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_ot_shaper_font_data_t {};
+
+hb_ot_shaper_font_data_t *
+_hb_ot_shaper_font_data_create (hb_font_t *font)
+{
+ return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+hb_ot_shaper_shape_plan_data_t *
+_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
+ if (unlikely (!plan))
+ return NULL;
+
+ hb_ot_shape_planner_t planner (shape_plan);
+
+ planner.shaper = hb_ot_shape_complex_categorize (&planner);
+
+ hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
+
+ planner.compile (*plan);
+
+ if (plan->shaper->data_create) {
+ plan->data = plan->shaper->data_create (plan);
+ if (unlikely (!plan->data))
+ return NULL;
+ }
+
+ return plan;
+}
+
+void
+_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
+{
+ if (plan->shaper->data_destroy)
+ plan->shaper->data_destroy (const_cast<void *> (plan->data));
+
+ plan->finish ();
+
+ free (plan);
+}
+
+
+/*
+ * shaper
+ */
+
+struct hb_ot_shape_context_t
+{
+ hb_ot_shape_plan_t *plan;
+ hb_font_t *font;
+ hb_face_t *face;
+ hb_buffer_t *buffer;
+ const hb_feature_t *user_features;
+ unsigned int num_user_features;
+
+ /* Transient stuff */
+ hb_direction_t target_direction;
+};
+
+
+
+/* Main shaper */
+
+
+/* Prepare */
+
+static void
+hb_set_unicode_props (hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode);
+}
+
+static void
+hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
+{
+ if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
+ _hb_glyph_info_get_general_category (&buffer->info[0]) !=
+ HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ return;
+
+ hb_codepoint_t dottedcircle_glyph;
+ if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
+ return;
+
+ hb_glyph_info_t dottedcircle;
+ dottedcircle.codepoint = 0x25CC;
+ _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
+
+ buffer->clear_output ();
+
+ buffer->idx = 0;
+ hb_glyph_info_t info = dottedcircle;
+ info.cluster = buffer->cur().cluster;
+ info.mask = buffer->cur().mask;
+ buffer->output_info (info);
+ while (buffer->idx < buffer->len)
+ buffer->next_glyph ();
+
+ buffer->swap_buffers ();
+}
+
+static void
+hb_form_clusters (hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 1; i < count; i++)
+ if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
+ buffer->merge_clusters (i - 1, i + 1);
+}
+
+static void
+hb_ensure_native_direction (hb_buffer_t *buffer)
+{
+ hb_direction_t direction = buffer->props.direction;
+
+ /* TODO vertical:
+ * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType
+ * Ogham fonts are supposed to be implemented BTT or not. Need to research that
+ * first. */
+ if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) ||
+ (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB))
+ {
+ hb_buffer_reverse_clusters (buffer);
+ buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction);
+ }
+}
+
+
+/* Substitute */
+
+static inline void
+hb_ot_mirror_chars (hb_ot_shape_context_t *c)
+{
+ if (HB_DIRECTION_IS_FORWARD (c->target_direction))
+ return;
+
+ hb_unicode_funcs_t *unicode = c->buffer->unicode;
+ hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
+
+ unsigned int count = c->buffer->len;
+ for (unsigned int i = 0; i < count; i++) {
+ hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint);
+ if (likely (codepoint == c->buffer->info[i].codepoint))
+ c->buffer->info[i].mask |= rtlm_mask;
+ else
+ c->buffer->info[i].codepoint = codepoint;
+ }
+}
+
+static inline void
+hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
+{
+ hb_ot_map_t *map = &c->plan->map;
+
+ hb_mask_t global_mask = map->get_global_mask ();
+ c->buffer->reset_masks (global_mask);
+
+ if (c->plan->shaper->setup_masks)
+ c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
+
+ for (unsigned int i = 0; i < c->num_user_features; i++)
+ {
+ const hb_feature_t *feature = &c->user_features[i];
+ if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
+ unsigned int shift;
+ hb_mask_t mask = map->get_mask (feature->tag, &shift);
+ c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
+ }
+ }
+}
+
+static inline void
+hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
+{
+ /* Normalization process sets up glyph_index(), we just copy it. */
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ buffer->info[i].codepoint = buffer->info[i].glyph_index();
+}
+
+static inline void
+hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
+{
+ unsigned int count = c->buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK :
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+}
+
+static inline void
+hb_ot_substitute_default (hb_ot_shape_context_t *c)
+{
+ if (c->plan->shaper->preprocess_text)
+ c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
+
+ hb_ot_mirror_chars (c);
+
+ HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
+
+ _hb_ot_shape_normalize (c->plan, c->buffer, c->font);
+
+ hb_ot_shape_setup_masks (c);
+
+ /* This is unfortunate to go here, but necessary... */
+ if (!hb_ot_layout_has_positioning (c->face))
+ _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buffer);
+
+ hb_ot_map_glyphs_fast (c->buffer);
+
+ HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index);
+}
+
+static inline void
+hb_ot_substitute_complex (hb_ot_shape_context_t *c)
+{
+ hb_ot_layout_substitute_start (c->font, c->buffer);
+
+ if (!hb_ot_layout_has_glyph_classes (c->face))
+ hb_synthesize_glyph_classes (c);
+
+ c->plan->substitute (c->font, c->buffer);
+
+ hb_ot_layout_substitute_finish (c->font, c->buffer);
+
+ return;
+}
+
+static inline void
+hb_ot_substitute (hb_ot_shape_context_t *c)
+{
+ hb_ot_substitute_default (c);
+ hb_ot_substitute_complex (c);
+}
+
+/* Position */
+
+static inline void
+zero_mark_widths_by_unicode (hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ {
+ buffer->pos[i].x_advance = 0;
+ buffer->pos[i].y_advance = 0;
+ }
+}
+
+static inline void
+zero_mark_widths_by_gdef (hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+ {
+ buffer->pos[i].x_advance = 0;
+ buffer->pos[i].y_advance = 0;
+ }
+}
+
+static inline void
+hb_ot_position_default (hb_ot_shape_context_t *c)
+{
+ hb_ot_layout_position_start (c->font, c->buffer);
+
+ unsigned int count = c->buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
+ c->buffer->props.direction,
+ &c->buffer->pos[i].x_advance,
+ &c->buffer->pos[i].y_advance);
+ c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+ c->buffer->props.direction,
+ &c->buffer->pos[i].x_offset,
+ &c->buffer->pos[i].y_offset);
+
+ }
+
+ switch (c->plan->shaper->zero_width_marks)
+ {
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+ zero_mark_widths_by_gdef (c->buffer);
+ break;
+
+ /* Not currently used for any shaper:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
+ zero_mark_widths_by_unicode (c->buffer);
+ break;
+ */
+
+ default:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+ break;
+ }
+}
+
+static inline bool
+hb_ot_position_complex (hb_ot_shape_context_t *c)
+{
+ bool ret = false;
+ unsigned int count = c->buffer->len;
+
+ if (hb_ot_layout_has_positioning (c->face))
+ {
+ /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
+
+ for (unsigned int i = 0; i < count; i++) {
+ c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+ HB_DIRECTION_LTR,
+ &c->buffer->pos[i].x_offset,
+ &c->buffer->pos[i].y_offset);
+ }
+
+ c->plan->position (c->font, c->buffer);
+
+ for (unsigned int i = 0; i < count; i++) {
+ c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+ HB_DIRECTION_LTR,
+ &c->buffer->pos[i].x_offset,
+ &c->buffer->pos[i].y_offset);
+ }
+
+ ret = true;
+ }
+
+ switch (c->plan->shaper->zero_width_marks)
+ {
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
+ zero_mark_widths_by_unicode (c->buffer);
+ break;
+
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+ zero_mark_widths_by_gdef (c->buffer);
+ break;
+
+ default:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+ //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+ break;
+ }
+
+ hb_ot_layout_position_finish (c->font, c->buffer);
+
+ return ret;
+}
+
+static inline void
+hb_ot_position (hb_ot_shape_context_t *c)
+{
+ hb_ot_position_default (c);
+
+ hb_bool_t fallback = !hb_ot_position_complex (c);
+
+ if (fallback && c->plan->shaper->fallback_position)
+ _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
+
+ if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
+ hb_buffer_reverse (c->buffer);
+
+ /* Visual fallback goes here. */
+
+ if (fallback)
+ _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
+}
+
+
+/* Post-process */
+
+static void
+hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
+{
+ if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
+ return;
+
+ hb_codepoint_t space = 0;
+
+ unsigned int count = c->buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!is_a_ligature (c->buffer->info[i]) &&
+ _hb_glyph_info_is_default_ignorable (&c->buffer->info[i])))
+ {
+ if (!space) {
+ /* We assume that the space glyph is not gid0. */
+ if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space)
+ return; /* No point! */
+ }
+ c->buffer->info[i].codepoint = space;
+ c->buffer->pos[i].x_advance = 0;
+ c->buffer->pos[i].y_advance = 0;
+ }
+}
+
+
+/* Pull it all together! */
+
+static void
+hb_ot_shape_internal (hb_ot_shape_context_t *c)
+{
+ c->buffer->deallocate_var_all ();
+
+ /* Save the original direction, we use it later. */
+ c->target_direction = c->buffer->props.direction;
+
+ HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
+ HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
+
+ c->buffer->clear_output ();
+
+ hb_set_unicode_props (c->buffer);
+ hb_insert_dotted_circle (c->buffer, c->font);
+ hb_form_clusters (c->buffer);
+
+ hb_ensure_native_direction (c->buffer);
+
+ hb_ot_substitute (c);
+ hb_ot_position (c);
+
+ hb_ot_hide_default_ignorables (c);
+
+ HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
+ HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
+
+ c->buffer->props.direction = c->target_direction;
+
+ c->buffer->deallocate_var_all ();
+}
+
+
+hb_bool_t
+_hb_ot_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features};
+ hb_ot_shape_internal (&c);
+
+ return true;
+}
+
+
+void
+hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
+ hb_tag_t table_tag,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ /* XXX Does the first part always succeed? */
+ HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes);
+}
+
+
+/* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */
+static void
+add_char (hb_font_t *font,
+ hb_unicode_funcs_t *unicode,
+ hb_bool_t mirror,
+ hb_codepoint_t u,
+ hb_set_t *glyphs)
+{
+ hb_codepoint_t glyph;
+ if (font->get_glyph (u, 0, &glyph))
+ glyphs->add (glyph);
+ if (mirror)
+ {
+ hb_codepoint_t m = unicode->mirroring (u);
+ if (m != u && font->get_glyph (m, 0, &glyph))
+ glyphs->add (glyph);
+ }
+}
+
+
+void
+hb_ot_shape_glyphs_closure (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features,
+ hb_set_t *glyphs)
+{
+ hb_ot_shape_plan_t plan;
+
+ const char *shapers[] = {"ot", NULL};
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
+ features, num_features, shapers);
+
+ bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
+
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs);
+
+ hb_set_t lookups;
+ lookups.init ();
+ hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
+
+ /* And find transitive closure. */
+ hb_set_t copy;
+ copy.init ();
+ do {
+ copy.set (glyphs);
+ for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index);)
+ hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
+ } while (!copy.is_equal (glyphs));
+
+ hb_shape_plan_destroy (shape_plan);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
new file mode 100644
index 0000000000..91ebec76ee
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
@@ -0,0 +1,722 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2011 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
+ */
+
+#include "hb-private.hh"
+#include "hb-ot.h"
+
+#include <string.h>
+
+
+
+/* hb_script_t */
+
+static hb_tag_t
+hb_ot_old_tag_from_script (hb_script_t script)
+{
+ /* This seems to be accurate as of end of 2012. */
+
+ switch ((hb_tag_t) script) {
+ case HB_SCRIPT_INVALID: return HB_OT_TAG_DEFAULT_SCRIPT;
+
+ /* KATAKANA and HIRAGANA both map to 'kana' */
+ case HB_SCRIPT_HIRAGANA: return HB_TAG('k','a','n','a');
+
+ /* Spaces at the end are preserved, unlike ISO 15924 */
+ case HB_SCRIPT_LAO: return HB_TAG('l','a','o',' ');
+ case HB_SCRIPT_YI: return HB_TAG('y','i',' ',' ');
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_NKO: return HB_TAG('n','k','o',' ');
+ /* Unicode-5.1 additions */
+ case HB_SCRIPT_VAI: return HB_TAG('v','a','i',' ');
+ /* Unicode-5.2 additions */
+ /* Unicode-6.0 additions */
+ }
+
+ /* Else, just change first char to lowercase and return */
+ return ((hb_tag_t) script) | 0x20000000;
+}
+
+static hb_script_t
+hb_ot_old_tag_to_script (hb_tag_t tag)
+{
+ if (unlikely (tag == HB_OT_TAG_DEFAULT_SCRIPT))
+ return HB_SCRIPT_INVALID;
+
+ /* This side of the conversion is fully algorithmic. */
+
+ /* Any spaces at the end of the tag are replaced by repeating the last
+ * letter. Eg 'nko ' -> 'Nkoo' */
+ if (unlikely ((tag & 0x0000FF00) == 0x00002000))
+ tag |= (tag >> 8) & 0x0000FF00; /* Copy second letter to third */
+ if (unlikely ((tag & 0x000000FF) == 0x00000020))
+ tag |= (tag >> 8) & 0x000000FF; /* Copy third letter to fourth */
+
+ /* Change first char to uppercase and return */
+ return (hb_script_t) (tag & ~0x20000000);
+}
+
+static hb_tag_t
+hb_ot_new_tag_from_script (hb_script_t script)
+{
+ switch ((hb_tag_t) script) {
+ case HB_SCRIPT_BENGALI: return HB_TAG('b','n','g','2');
+ case HB_SCRIPT_DEVANAGARI: return HB_TAG('d','e','v','2');
+ case HB_SCRIPT_GUJARATI: return HB_TAG('g','j','r','2');
+ case HB_SCRIPT_GURMUKHI: return HB_TAG('g','u','r','2');
+ case HB_SCRIPT_KANNADA: return HB_TAG('k','n','d','2');
+ case HB_SCRIPT_MALAYALAM: return HB_TAG('m','l','m','2');
+ case HB_SCRIPT_ORIYA: return HB_TAG('o','r','y','2');
+ case HB_SCRIPT_TAMIL: return HB_TAG('t','m','l','2');
+ case HB_SCRIPT_TELUGU: return HB_TAG('t','e','l','2');
+ case HB_SCRIPT_MYANMAR: return HB_TAG('m','y','m','2');
+ }
+
+ return HB_OT_TAG_DEFAULT_SCRIPT;
+}
+
+static hb_script_t
+hb_ot_new_tag_to_script (hb_tag_t tag)
+{
+ switch (tag) {
+ case HB_TAG('b','n','g','2'): return HB_SCRIPT_BENGALI;
+ case HB_TAG('d','e','v','2'): return HB_SCRIPT_DEVANAGARI;
+ case HB_TAG('g','j','r','2'): return HB_SCRIPT_GUJARATI;
+ case HB_TAG('g','u','r','2'): return HB_SCRIPT_GURMUKHI;
+ case HB_TAG('k','n','d','2'): return HB_SCRIPT_KANNADA;
+ case HB_TAG('m','l','m','2'): return HB_SCRIPT_MALAYALAM;
+ case HB_TAG('o','r','y','2'): return HB_SCRIPT_ORIYA;
+ case HB_TAG('t','m','l','2'): return HB_SCRIPT_TAMIL;
+ case HB_TAG('t','e','l','2'): return HB_SCRIPT_TELUGU;
+ case HB_TAG('m','y','m','2'): return HB_SCRIPT_MYANMAR;
+ }
+
+ return HB_SCRIPT_UNKNOWN;
+}
+
+/*
+ * Complete list at:
+ * https://www.microsoft.com/typography/otspec/scripttags.htm
+ * https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm
+ *
+ * Most of the script tags are the same as the ISO 15924 tag but lowercased.
+ * So we just do that, and handle the exceptional cases in a switch.
+ */
+
+void
+hb_ot_tags_from_script (hb_script_t script,
+ hb_tag_t *script_tag_1,
+ hb_tag_t *script_tag_2)
+{
+ hb_tag_t new_tag;
+
+ *script_tag_2 = HB_OT_TAG_DEFAULT_SCRIPT;
+ *script_tag_1 = hb_ot_old_tag_from_script (script);
+
+ new_tag = hb_ot_new_tag_from_script (script);
+ if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) {
+ *script_tag_2 = *script_tag_1;
+ *script_tag_1 = new_tag;
+ }
+}
+
+hb_script_t
+hb_ot_tag_to_script (hb_tag_t tag)
+{
+ if (unlikely ((tag & 0x000000FF) == '2'))
+ return hb_ot_new_tag_to_script (tag);
+
+ return hb_ot_old_tag_to_script (tag);
+}
+
+
+/* hb_language_t */
+
+typedef struct {
+ char language[6];
+ hb_tag_t tag;
+} LangTag;
+
+/*
+ * Complete list at:
+ * http://www.microsoft.com/typography/otspec/languagetags.htm
+ *
+ * Generated by intersecting the OpenType language tag list from
+ * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
+ * 2008/08/04, matching on name, and finally adjusted manually.
+ *
+ * Updated on 2012/12/07 with more research into remaining codes.
+ *
+ * Some items still missing. Those are commented out at the end.
+ * Keep sorted for bsearch.
+ */
+
+static const LangTag ot_languages[] = {
+ {"aa", HB_TAG('A','F','R',' ')}, /* Afar */
+ {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
+ {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
+ {"ada", HB_TAG('D','N','G',' ')}, /* Dangme */
+ {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
+ {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
+ {"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */
+ {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
+ {"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */
+ {"am", HB_TAG('A','M','H',' ')}, /* Amharic */
+ {"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */
+ {"ar", HB_TAG('A','R','A',' ')}, /* Arabic */
+ {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
+ {"as", HB_TAG('A','S','M',' ')}, /* Assamese */
+ {"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */
+ {"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */
+ {"av", HB_TAG('A','V','R',' ')}, /* Avaric */
+ {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
+ {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */
+ {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */
+ {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
+ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
+ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */
+ {"bci", HB_TAG('B','A','U',' ')}, /* Baule */
+ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
+ {"be", HB_TAG('B','E','L',' ')}, /* Belarussian */
+ {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
+ {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */
+ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
+ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */
+ {"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */
+ {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
+ {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
+ {"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
+ {"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
+ {"bin", HB_TAG('E','D','O',' ')}, /* Bini */
+ {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */
+ {"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */
+ {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */
+ {"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
+ {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
+ {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
+ {"br", HB_TAG('B','R','E',' ')}, /* Breton */
+ {"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */
+ {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
+ {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
+ {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
+ {"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */
+ {"byn", HB_TAG('B','I','L',' ')}, /* Bilen */
+ {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
+ {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
+ {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
+ {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
+ {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
+ {"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
+ {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
+ {"cr", HB_TAG('C','R','E',' ')}, /* Cree */
+ {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
+ {"crj", HB_TAG('E','C','R',' ')}, /* [Southern] East Cree */
+ {"crl", HB_TAG('E','C','R',' ')}, /* [Northern] East Cree */
+ {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
+ {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
+ {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
+ {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
+ {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
+ {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
+ {"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
+ {"da", HB_TAG('D','A','N',' ')}, /* Danish */
+ {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
+ {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
+ {"de", HB_TAG('D','E','U',' ')}, /* German */
+ {"din", HB_TAG('D','N','K',' ')}, /* Dinka */
+ {"dje", HB_TAG('D','J','R',' ')}, /* Djerma */
+ {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
+ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
+ {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
+ {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
+ {"dyu", HB_TAG('J','U','L',' ')}, /* Jula */
+ {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
+ {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
+ {"efi", HB_TAG('E','F','I',' ')}, /* Efik */
+ {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
+ {"en", HB_TAG('E','N','G',' ')}, /* English */
+ {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
+ {"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
+ {"es", HB_TAG('E','S','P',' ')}, /* Spanish */
+ {"et", HB_TAG('E','T','I',' ')}, /* Estonian */
+ {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
+ {"eve", HB_TAG('E','V','N',' ')}, /* Even */
+ {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
+ {"fa", HB_TAG('F','A','R',' ')}, /* Persian */
+ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah */
+ {"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
+ {"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
+ {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
+ {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
+ {"fon", HB_TAG('F','O','N',' ')}, /* Fon */
+ {"fr", HB_TAG('F','R','A',' ')}, /* French */
+ {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
+ {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
+ {"ga", HB_TAG('I','R','I',' ')}, /* Irish */
+ {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
+ {"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */
+ {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
+ {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
+ {"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */
+ {"gl", HB_TAG('G','A','L',' ')}, /* Galician */
+ {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
+ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani */
+ {"gon", HB_TAG('G','O','N',' ')}, /* Gondi */
+ {"grt", HB_TAG('G','R','O',' ')}, /* Garo */
+ {"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */
+ {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
+ {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
+ {"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
+ {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
+ {"har", HB_TAG('H','R','I',' ')}, /* Harari */
+ {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiin */
+ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
+ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
+ {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
+ {"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
+ {"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
+ {"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */
+ {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
+ {"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */
+ {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
+ {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
+ {"ht", HB_TAG('H','A','I',' ')}, /* Haitian */
+ {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
+ {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
+ {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
+ {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
+ {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
+ {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */
+ {"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */
+ {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
+ {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
+ {"it", HB_TAG('I','T','A',' ')}, /* Italian */
+ {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */
+ {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
+ {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
+ {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
+ {"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
+ {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
+ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
+ {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
+ {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
+ {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
+ {"kex", HB_TAG('K','K','N',' ')}, /* Kokni */
+ {"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
+ {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
+ {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
+ {"khb", HB_TAG('X','B','D',' ')}, /* Tai Lue */
+ {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
+ {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
+ {"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */
+ {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
+ {"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
+ {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
+ {"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
+ {"kmb", HB_TAG('M','B','N',' ')}, /* [North] Mbundu */
+ {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
+ {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
+ {"ko", HB_TAG('K','O','R',' ')}, /* Korean */
+ {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
+ {"kok", HB_TAG('K','O','K',' ')}, /* Konkani */
+ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */
+ {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
+ {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
+ {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
+ {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */
+ {"kri", HB_TAG('K','R','I',' ')}, /* Krio */
+ {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
+ {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
+ {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
+ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
+ {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
+ {"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
+ {"kxc", HB_TAG('K','M','S',' ')}, /* Komso */
+ {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
+ {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
+ {"la", HB_TAG('L','A','T',' ')}, /* Latin */
+ {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
+ {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
+ {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
+ {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
+ {"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */
+ {"lg", HB_TAG('L','U','G',' ')}, /* Luganda */
+ {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
+ {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
+ {"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */
+ {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
+ {"lo", HB_TAG('L','A','O',' ')}, /* Lao */
+ {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
+ {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
+ {"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */
+ {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
+ {"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */
+ {"luy", HB_TAG('L','U','H',' ')}, /* Luhya [macrolanguage] */
+ {"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
+ {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
+ {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
+ {"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
+ {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
+ {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
+ {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
+ {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
+ {"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */
+ {"mi", HB_TAG('M','R','I',' ')}, /* Maori */
+ {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
+ {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
+ {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */
+ {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
+ {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
+ {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
+ {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */
+ {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
+ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
+ {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
+ {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
+ {"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
+ {"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */
+ {"ms", HB_TAG('M','L','Y',' ')}, /* Malay */
+ {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
+ {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
+ {"my", HB_TAG('B','R','M',' ')}, /* Burmese */
+ {"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
+ {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
+ {"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */
+ {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
+ {"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
+ {"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */
+ {"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
+ {"new", HB_TAG('N','E','W',' ')}, /* Newari */
+ {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
+ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
+ {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
+ {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
+ {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
+ {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
+ {"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */
+ {"nod", HB_TAG('N','T','A',' ')}, /* Northern Tai */
+ {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
+ {"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
+ {"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */
+ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
+ {"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */
+ {"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */
+ {"nyn", HB_TAG('N','K','L',' ')}, /* Nkole */
+ {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
+ {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
+ {"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */
+ {"om", HB_TAG('O','R','O',' ')}, /* Oromo */
+ {"or", HB_TAG('O','R','I',' ')}, /* Oriya */
+ {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
+ {"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
+ {"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
+ {"pi", HB_TAG('P','A','L',' ')}, /* Pali */
+ {"pl", HB_TAG('P','L','K',' ')}, /* Polish */
+ {"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */
+ {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
+ {"prs", HB_TAG('D','R','I',' ')}, /* Dari */
+ {"ps", HB_TAG('P','A','S',' ')}, /* Pushto */
+ {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
+ {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
+ {"rbb", HB_TAG('P','L','G',' ')}, /* [Rumai] Palaung */
+ {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
+ {"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
+ {"rki", HB_TAG('A','R','K',' ')}, /* Arakanese */
+ {"rm", HB_TAG('R','M','S',' ')}, /* Rhaeto-Romanic */
+ {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
+ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
+ {"ru", HB_TAG('R','U','S',' ')}, /* Russian */
+ {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
+ {"rw", HB_TAG('R','U','A',' ')}, /* Ruanda */
+ {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
+ {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
+ {"sat", HB_TAG('S','A','T',' ')}, /* Santali */
+ {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
+ {"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */
+ {"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
+ {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
+ {"seh", HB_TAG('S','N','A',' ')}, /* Sena */
+ {"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
+ {"sg", HB_TAG('S','G','O',' ')}, /* Sango */
+ {"shn", HB_TAG('S','H','N',' ')}, /* Shan */
+ {"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
+ {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
+ {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */
+ {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */
+ {"skr", HB_TAG('S','R','K',' ')}, /* Seraiki */
+ {"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
+ {"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
+ {"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
+ {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
+ {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
+ {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
+ {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
+ {"so", HB_TAG('S','M','L',' ')}, /* Somali */
+ {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
+ {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
+ {"srr", HB_TAG('S','R','R',' ')}, /* Serer */
+ {"ss", HB_TAG('S','W','Z',' ')}, /* Swazi */
+ {"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */
+ {"suq", HB_TAG('S','U','R',' ')}, /* Suri */
+ {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
+ {"sva", HB_TAG('S','V','A',' ')}, /* Svan */
+ {"sw", HB_TAG('S','W','K',' ')}, /* Swahili */
+ {"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
+ {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
+ {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
+ {"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
+ {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
+ {"te", HB_TAG('T','E','L',' ')}, /* Telugu */
+ {"tem", HB_TAG('T','M','N',' ')}, /* Temne */
+ {"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
+ {"th", HB_TAG('T','H','A',' ')}, /* Thai */
+ {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
+ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
+ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
+ {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
+ {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */
+ {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
+ {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */
+ {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
+ {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
+ {"tw", HB_TAG('T','W','I',' ')}, /* Twi */
+ {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
+ {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */
+ {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
+ {"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
+ {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
+ {"umb", HB_TAG('M','B','N',' ')}, /* [South] Mbundu */
+ {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
+ {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
+ {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
+ {"ve", HB_TAG('V','E','N',' ')}, /* Venda */
+ {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
+ {"vmw", HB_TAG('M','A','K',' ')}, /* Makua */
+ {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
+ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
+ {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
+ {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
+ {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
+ {"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
+ {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
+ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */
+ {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
+ {"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
+ {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
+ {"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
+
+ /* The corresponding languages IDs for the following IDs are unclear,
+ * overlap, or are architecturally weird. Needs more research. */
+
+/*{"ahg/awn/xan?", HB_TAG('A','G','W',' ')},*/ /* Agaw */
+/*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
+/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */
+/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
+/*{"sgw?", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
+/*{"acf/gcf?", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
+/*{"vls/nl-be", HB_TAG('F','L','E',' ')},*/ /* Flemish */
+/*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
+/*{"fuf?", HB_TAG('F','T','A',' ')},*/ /* Futa */
+/*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
+/*{"cfm/rnl?", HB_TAG('H','A','L',' ')},*/ /* Halam */
+/*{"ga-Latg?/Latg?", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
+/*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */
+/*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/ /* Kebena */
+/*{"Geok", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */
+/*{"kca", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */
+/*{"kca", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */
+/*{"kca", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */
+/*{"guz?/kqs?/kss?", HB_TAG('K','I','S',' ')},*/ /* Kisii */
+/*{"kfa/kfi?/kpb?/xua?/xuj?", HB_TAG('K','O','D',' ')},*/ /* Kodagu */
+/*{"okm?/oko?", HB_TAG('K','O','H',' ')},*/ /* Korean Old Hangul */
+/*{"kon?/ktu?/...", HB_TAG('K','O','N',' ')},*/ /* Kikongo */
+/*{"kfx?", HB_TAG('K','U','L',' ')},*/ /* Kulvi */
+/*{"??", HB_TAG('L','A','H',' ')},*/ /* Lahuli */
+/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
+/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
+/*{"mnk?/mlq?/...", HB_TAG('M','L','N',' ')},*/ /* Malinke */
+/*{"man?/myq?/mku?/msc?/...", HB_TAG('M','N','K',' ')},*/ /* Maninka */
+/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */
+/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
+/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
+/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
+/*{"polyton", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */
+/*{"??", HB_TAG('Q','I','N',' ')},*/ /* Asho Chin */
+/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
+/*{"chp?", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
+/*{"xan?", HB_TAG('S','E','K',' ')},*/ /* Sekota */
+/*{"stv/wle?/xst?", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
+/*{"ngo?", HB_TAG('S','X','T',' ')},*/ /* Sutu */
+/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
+/*{"tnz?/tog?/toi?", HB_TAG('T','N','G',' ')},*/ /* Tonga */
+/*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
+/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */
+/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */
+/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
+/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
+/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
+/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
+};
+
+static const LangTag ot_languages_zh[] = {
+ {"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */
+ {"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
+ {"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */
+ {"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */
+ {"zh-tw", HB_TAG('Z','H','T',' ')} /* Chinese (Taiwan) */
+};
+
+static int
+lang_compare_first_component (const char *a,
+ const char *b)
+{
+ unsigned int da, db;
+ const char *p;
+
+ p = strchr (a, '-');
+ da = p ? (unsigned int) (p - a) : strlen (a);
+
+ p = strchr (b, '-');
+ db = p ? (unsigned int) (p - b) : strlen (b);
+
+ return strncmp (a, b, MAX (da, db));
+}
+
+static hb_bool_t
+lang_matches (const char *lang_str, const char *spec)
+{
+ unsigned int len = strlen (spec);
+
+ return strncmp (lang_str, spec, len) == 0 &&
+ (lang_str[len] == '\0' || lang_str[len] == '-');
+}
+
+hb_tag_t
+hb_ot_tag_from_language (hb_language_t language)
+{
+ const char *lang_str, *s;
+ const LangTag *lang_tag;
+
+ if (language == HB_LANGUAGE_INVALID)
+ return HB_OT_TAG_DEFAULT_LANGUAGE;
+
+ lang_str = hb_language_to_string (language);
+
+ s = strstr (lang_str, "x-hbot");
+ if (s) {
+ char tag[4];
+ int i;
+ s += 6;
+ for (i = 0; i < 4 && ISALPHA (s[i]); i++)
+ tag[i] = TOUPPER (s[i]);
+ if (i) {
+ for (; i < 4; i++)
+ tag[i] = ' ';
+ return HB_TAG_CHAR4 (tag);
+ }
+ }
+
+ /* Find a language matching in the first component */
+ lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
+ ARRAY_LENGTH (ot_languages), sizeof (LangTag),
+ (hb_compare_func_t) lang_compare_first_component);
+ if (lang_tag)
+ return lang_tag->tag;
+
+ /* Otherwise, check the Chinese ones */
+ if (0 == lang_compare_first_component (lang_str, "zh"))
+ {
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++)
+ {
+ lang_tag = &ot_languages_zh[i];
+ if (lang_matches (lang_tag->language, lang_str))
+ return lang_tag->tag;
+ }
+
+ /* Otherwise just return 'ZHS ' */
+ return HB_TAG('Z','H','S',' ');
+ }
+
+ s = strchr (lang_str, '-');
+ if (!s)
+ s = lang_str + strlen (lang_str);
+ if (s - lang_str == 3) {
+ /* Assume it's ISO-639-3 and upper-case and use it. */
+ return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000;
+ }
+
+ return HB_OT_TAG_DEFAULT_LANGUAGE;
+}
+
+hb_language_t
+hb_ot_tag_to_language (hb_tag_t tag)
+{
+ unsigned int i;
+
+ if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
+ return NULL;
+
+ for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
+ if (ot_languages[i].tag == tag)
+ return hb_language_from_string (ot_languages[i].language, -1);
+
+ /* If tag starts with ZH, it's Chinese */
+ if ((tag & 0xFFFF0000) == 0x5A480000) {
+ switch (tag) {
+ case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */
+ default: {
+ /* Encode the tag... */
+ unsigned char buf[14] = "zh-x-hbot";
+ buf[9] = tag >> 24;
+ buf[10] = (tag >> 16) & 0xFF;
+ buf[11] = (tag >> 8) & 0xFF;
+ buf[12] = tag & 0xFF;
+ if (buf[12] == 0x20)
+ buf[12] = '\0';
+ buf[13] = '\0';
+ return hb_language_from_string ((char *) buf, -1);
+ }
+ }
+ }
+
+ /* Else return a custom language in the form of "x-hbotABCD" */
+ {
+ unsigned char buf[11] = "x-hbot";
+ buf[6] = tag >> 24;
+ buf[7] = (tag >> 16) & 0xFF;
+ buf[8] = (tag >> 8) & 0xFF;
+ buf[9] = tag & 0xFF;
+ if (buf[9] == 0x20)
+ buf[9] = '\0';
+ buf[10] = '\0';
+ return hb_language_from_string ((char *) buf, -1);
+ }
+}
+
+
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h
new file mode 100644
index 0000000000..1bf12ab3c0
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_TAG_H
+#define HB_OT_TAG_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+
+#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T')
+#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't')
+
+void
+hb_ot_tags_from_script (hb_script_t script,
+ hb_tag_t *script_tag_1,
+ hb_tag_t *script_tag_2);
+
+hb_script_t
+hb_ot_tag_to_script (hb_tag_t tag);
+
+hb_tag_t
+hb_ot_tag_from_language (hb_language_t language);
+
+hb_language_t
+hb_ot_tag_to_language (hb_tag_t tag);
+
+
+HB_END_DECLS
+
+#endif /* HB_OT_TAG_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot.h b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
new file mode 100644
index 0000000000..8073906399
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H
+#define HB_OT_H
+#define HB_OT_H_IN
+
+#include "hb.h"
+
+#include "hb-ot-layout.h"
+#include "hb-ot-tag.h"
+
+HB_BEGIN_DECLS
+
+/* TODO remove */
+void
+hb_ot_shape_glyphs_closure (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features,
+ hb_set_t *glyphs);
+
+HB_END_DECLS
+
+#undef HB_OT_H_IN
+#endif /* HB_OT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
new file mode 100644
index 0000000000..4152e27552
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
@@ -0,0 +1,909 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_PRIVATE_HH
+#define HB_PRIVATE_HH
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hb.h"
+#define HB_H_IN
+#ifdef HAVE_OT
+#include "hb-ot.h"
+#define HB_OT_H_IN
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+/* We only use these two for debug output. However, the debug code is
+ * always seen by the compiler (and optimized out in non-debug builds.
+ * If including these becomes a problem, we can start thinking about
+ * someway around that. */
+#include <stdio.h>
+#include <errno.h>
+#include <stdarg.h>
+
+
+
+/* Essentials */
+
+#ifndef NULL
+# define NULL ((void *) 0)
+#endif
+
+
+/* Void! */
+struct _hb_void_t {};
+typedef const _hb_void_t &hb_void_t;
+#define HB_VOID (* (const _hb_void_t *) NULL)
+
+
+/* Basics */
+
+
+#undef MIN
+template <typename Type>
+static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
+
+#undef MAX
+template <typename Type>
+static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
+
+
+#undef ARRAY_LENGTH
+template <typename Type, unsigned int n>
+static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
+/* A const version, but does not detect erratically being called on pointers. */
+#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
+
+#define HB_STMT_START do
+#define HB_STMT_END while (0)
+
+#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
+#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
+#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
+
+#define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1]))
+#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1]))
+
+#define _PASTE1(a,b) a##b
+#define PASTE(a,b) _PASTE1(a,b)
+
+/* Lets assert int types. Saves trouble down the road. */
+
+ASSERT_STATIC (sizeof (int8_t) == 1);
+ASSERT_STATIC (sizeof (uint8_t) == 1);
+ASSERT_STATIC (sizeof (int16_t) == 2);
+ASSERT_STATIC (sizeof (uint16_t) == 2);
+ASSERT_STATIC (sizeof (int32_t) == 4);
+ASSERT_STATIC (sizeof (uint32_t) == 4);
+ASSERT_STATIC (sizeof (int64_t) == 8);
+ASSERT_STATIC (sizeof (uint64_t) == 8);
+
+ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
+ASSERT_STATIC (sizeof (hb_position_t) == 4);
+ASSERT_STATIC (sizeof (hb_mask_t) == 4);
+ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
+
+
+/* We like our types POD */
+
+#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
+#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
+#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type)
+
+#ifdef __GNUC__
+# define _ASSERT_INSTANCE_POD1(_line, _instance) \
+ HB_STMT_START { \
+ typedef __typeof__(_instance) _type_##_line; \
+ _ASSERT_TYPE_POD1 (_line, _type_##_line); \
+ } HB_STMT_END
+#else
+# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested
+#endif
+# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance)
+# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
+
+/* Check _assertion in a method environment */
+#define _ASSERT_POD1(_line) \
+ inline void _static_assertion_on_line_##_line (void) const \
+ { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
+# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line)
+# define ASSERT_POD() _ASSERT_POD0 (__LINE__)
+
+
+
+/* Misc */
+
+
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
+#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
+#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
+#else
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
+#endif
+
+#ifndef __GNUC__
+#undef __attribute__
+#define __attribute__(x)
+#endif
+
+#if __GNUC__ >= 3
+#define HB_PURE_FUNC __attribute__((pure))
+#define HB_CONST_FUNC __attribute__((const))
+#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+#else
+#define HB_PURE_FUNC
+#define HB_CONST_FUNC
+#define HB_PRINTF_FUNC(format_idx, arg_idx)
+#endif
+#if __GNUC__ >= 4
+#define HB_UNUSED __attribute__((unused))
+#else
+#define HB_UNUSED
+#endif
+
+#ifndef HB_INTERNAL
+# ifndef __MINGW32__
+# define HB_INTERNAL __attribute__((__visibility__("hidden")))
+# else
+# define HB_INTERNAL
+# endif
+#endif
+
+
+#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
+#define snprintf _snprintf
+#endif
+
+#ifdef _MSC_VER
+#undef inline
+#define inline __inline
+#endif
+
+#ifdef __STRICT_ANSI__
+#undef inline
+#define inline __inline__
+#endif
+
+
+#if __GNUC__ >= 3
+#define HB_FUNC __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+#define HB_FUNC __FUNCSIG__
+#else
+#define HB_FUNC __func__
+#endif
+
+
+/* Return the number of 1 bits in mask. */
+static inline HB_CONST_FUNC unsigned int
+_hb_popcount32 (uint32_t mask)
+{
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+ return __builtin_popcount (mask);
+#else
+ /* "HACKMEM 169" */
+ register uint32_t y;
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return (((y + (y >> 3)) & 030707070707) % 077);
+#endif
+}
+
+/* Returns the number of bits needed to store number */
+static inline HB_CONST_FUNC unsigned int
+_hb_bit_storage (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+ return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
+#else
+ register unsigned int n_bits = 0;
+ while (number) {
+ n_bits++;
+ number >>= 1;
+ }
+ return n_bits;
+#endif
+}
+
+/* Returns the number of zero bits in the least significant side of number */
+static inline HB_CONST_FUNC unsigned int
+_hb_ctz (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+ return likely (number) ? __builtin_ctz (number) : 0;
+#else
+ register unsigned int n_bits = 0;
+ if (unlikely (!number)) return 0;
+ while (!(number & 1)) {
+ n_bits++;
+ number >>= 1;
+ }
+ return n_bits;
+#endif
+}
+
+static inline bool
+_hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
+{
+ return (size > 0) && (count >= ((unsigned int) -1) / size);
+}
+
+
+/* Type of bsearch() / qsort() compare function */
+typedef int (*hb_compare_func_t) (const void *, const void *);
+
+
+
+
+/* arrays and maps */
+
+
+#define HB_PREALLOCED_ARRAY_INIT {0}
+template <typename Type, unsigned int StaticSize>
+struct hb_prealloced_array_t
+{
+ unsigned int len;
+ unsigned int allocated;
+ Type *array;
+ Type static_array[StaticSize];
+
+ void init (void) { memset (this, 0, sizeof (*this)); }
+
+ inline Type& operator [] (unsigned int i) { return array[i]; }
+ inline const Type& operator [] (unsigned int i) const { return array[i]; }
+
+ inline Type *push (void)
+ {
+ if (!array) {
+ array = static_array;
+ allocated = ARRAY_LENGTH (static_array);
+ }
+ if (likely (len < allocated))
+ return &array[len++];
+
+ /* Need to reallocate */
+ unsigned int new_allocated = allocated + (allocated >> 1) + 8;
+ Type *new_array = NULL;
+
+ if (array == static_array) {
+ new_array = (Type *) calloc (new_allocated, sizeof (Type));
+ if (new_array)
+ memcpy (new_array, array, len * sizeof (Type));
+ } else {
+ bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
+ if (likely (!overflows)) {
+ new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
+ }
+ }
+
+ if (unlikely (!new_array))
+ return NULL;
+
+ array = new_array;
+ allocated = new_allocated;
+ return &array[len++];
+ }
+
+ inline void pop (void)
+ {
+ len--;
+ }
+
+ inline void remove (unsigned int i)
+ {
+ if (unlikely (i >= len))
+ return;
+ memmove (static_cast<void *> (&array[i]),
+ static_cast<void *> (&array[i + 1]),
+ (len - i - 1) * sizeof (Type));
+ len--;
+ }
+
+ inline void shrink (unsigned int l)
+ {
+ if (l < len)
+ len = l;
+ }
+
+ template <typename T>
+ inline Type *find (T v) {
+ for (unsigned int i = 0; i < len; i++)
+ if (array[i] == v)
+ return &array[i];
+ return NULL;
+ }
+ template <typename T>
+ inline const Type *find (T v) const {
+ for (unsigned int i = 0; i < len; i++)
+ if (array[i] == v)
+ return &array[i];
+ return NULL;
+ }
+
+ inline void sort (void)
+ {
+ qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ }
+
+ inline void sort (unsigned int start, unsigned int end)
+ {
+ qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ }
+
+ template <typename T>
+ inline Type *bsearch (T *key)
+ {
+ return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ }
+ template <typename T>
+ inline const Type *bsearch (T *key) const
+ {
+ return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ }
+
+ inline void finish (void)
+ {
+ if (array != static_array)
+ free (array);
+ array = NULL;
+ allocated = len = 0;
+ }
+};
+
+#define HB_AUTO_ARRAY_PREALLOCED 16
+template <typename Type>
+struct hb_auto_array_t : hb_prealloced_array_t <Type, HB_AUTO_ARRAY_PREALLOCED>
+{
+ hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED>::init (); }
+ ~hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED>::finish (); }
+};
+
+
+#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
+template <typename item_t, typename lock_t>
+struct hb_lockable_set_t
+{
+ hb_prealloced_array_t <item_t, 2> items;
+
+ inline void init (void) { items.init (); }
+
+ template <typename T>
+ inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (item) {
+ if (replace) {
+ item_t old = *item;
+ *item = v;
+ l.unlock ();
+ old.finish ();
+ }
+ else {
+ item = NULL;
+ l.unlock ();
+ }
+ } else {
+ item = items.push ();
+ if (likely (item))
+ *item = v;
+ l.unlock ();
+ }
+ return item;
+ }
+
+ template <typename T>
+ inline void remove (T v, lock_t &l)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (item) {
+ item_t old = *item;
+ *item = items[items.len - 1];
+ items.pop ();
+ l.unlock ();
+ old.finish ();
+ } else {
+ l.unlock ();
+ }
+ }
+
+ template <typename T>
+ inline bool find (T v, item_t *i, lock_t &l)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (item)
+ *i = *item;
+ l.unlock ();
+ return !!item;
+ }
+
+ template <typename T>
+ inline item_t *find_or_insert (T v, lock_t &l)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (!item) {
+ item = items.push ();
+ if (likely (item))
+ *item = v;
+ }
+ l.unlock ();
+ return item;
+ }
+
+ inline void finish (lock_t &l)
+ {
+ if (!items.len) {
+ /* No need for locking. */
+ items.finish ();
+ return;
+ }
+ l.lock ();
+ while (items.len) {
+ item_t old = items[items.len - 1];
+ items.pop ();
+ l.unlock ();
+ old.finish ();
+ l.lock ();
+ }
+ items.finish ();
+ l.unlock ();
+ }
+
+};
+
+
+
+
+/* Big-endian handling */
+
+static inline uint16_t hb_be_uint16 (const uint16_t v)
+{
+ const uint8_t *V = (const uint8_t *) &v;
+ return (V[0] << 8) | V[1];
+}
+
+static inline uint16_t hb_uint16_swap (const uint16_t v)
+{
+ return (v >> 8) | (v << 8);
+}
+
+static inline uint32_t hb_uint32_swap (const uint32_t v)
+{
+ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16);
+}
+
+/* Note, of the following macros, uint16_get is the one called many many times.
+ * If there is any optimizations to be done, it's in that macro. However, I
+ * already confirmed that on my T400 ThinkPad at least, using bswap_16(), which
+ * results in a single ror instruction, does NOT speed this up. In fact, it
+ * resulted in a minor slowdown. At any rate, note that v may not be correctly
+ * aligned, so I think the current implementation is optimal.
+ */
+
+#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END
+#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1])
+#define hb_be_uint16_eq(a,b) (a[0] == b[0] && a[1] == b[1])
+
+#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END
+#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
+#define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
+
+#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] = (V); } HB_STMT_END
+#define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2])
+#define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2])
+
+
+/* ASCII tag/character handling */
+
+static inline bool ISALPHA (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
+static inline bool ISALNUM (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
+static inline bool ISSPACE (unsigned char c)
+{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
+static inline unsigned char TOUPPER (unsigned char c)
+{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
+static inline unsigned char TOLOWER (unsigned char c)
+{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
+
+#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \
+ ((const char *) s)[1], \
+ ((const char *) s)[2], \
+ ((const char *) s)[3]))
+
+
+/* C++ helpers */
+
+/* Makes class uncopyable. Use in private: section. */
+#define NO_COPY(T) \
+ T (const T &o); \
+ T &operator = (const T &o)
+
+
+/* Debug */
+
+
+#ifndef HB_DEBUG
+#define HB_DEBUG 0
+#endif
+
+static inline bool
+_hb_debug (unsigned int level,
+ unsigned int max_level)
+{
+ return level < max_level;
+}
+
+#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
+#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
+
+template <int max_level> static inline void
+_hb_debug_msg_va (const char *what,
+ const void *obj,
+ const char *func,
+ bool indented,
+ unsigned int level,
+ int level_dir,
+ const char *message,
+ va_list ap)
+{
+ if (!_hb_debug (level, max_level))
+ return;
+
+ fprintf (stderr, "%-10s", what ? what : "");
+
+ if (obj)
+ fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
+ else
+ fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
+
+ if (indented) {
+/* One may want to add ASCII version of these. See:
+ * https://bugs.freedesktop.org/show_bug.cgi?id=50970 */
+#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
+#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
+#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
+#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */
+ static const char bars[] = VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
+ fprintf (stderr, "%2u %s" VRBAR "%s",
+ level,
+ bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars), (unsigned int) (sizeof (VBAR) - 1) * level),
+ level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
+ } else
+ fprintf (stderr, " " VRBAR LBAR);
+
+ if (func)
+ {
+ unsigned int func_len = strlen (func);
+#ifndef HB_DEBUG_VERBOSE
+ /* Skip "typename" */
+ if (0 == strncmp (func, "typename ", 9))
+ func += 9;
+ /* Skip return type */
+ const char *space = strchr (func, ' ');
+ if (space)
+ func = space + 1;
+ /* Skip parameter list */
+ const char *paren = strchr (func, '(');
+ if (paren)
+ func_len = paren - func;
+#endif
+ fprintf (stderr, "%.*s: ", func_len, func);
+ }
+
+ if (message)
+ vfprintf (stderr, message, ap);
+
+ fprintf (stderr, "\n");
+}
+template <> inline void
+_hb_debug_msg_va<0> (const char *what HB_UNUSED,
+ const void *obj HB_UNUSED,
+ const char *func HB_UNUSED,
+ bool indented HB_UNUSED,
+ unsigned int level HB_UNUSED,
+ int level_dir HB_UNUSED,
+ const char *message HB_UNUSED,
+ va_list ap HB_UNUSED) {}
+
+template <int max_level> static inline void
+_hb_debug_msg (const char *what,
+ const void *obj,
+ const char *func,
+ bool indented,
+ unsigned int level,
+ int level_dir,
+ const char *message,
+ ...) HB_PRINTF_FUNC(7, 8);
+template <int max_level> static inline void
+_hb_debug_msg (const char *what,
+ const void *obj,
+ const char *func,
+ bool indented,
+ unsigned int level,
+ int level_dir,
+ const char *message,
+ ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
+ va_end (ap);
+}
+template <> inline void
+_hb_debug_msg<0> (const char *what HB_UNUSED,
+ const void *obj HB_UNUSED,
+ const char *func HB_UNUSED,
+ bool indented HB_UNUSED,
+ unsigned int level HB_UNUSED,
+ int level_dir HB_UNUSED,
+ const char *message HB_UNUSED,
+ ...) HB_PRINTF_FUNC(7, 8);
+template <> inline void
+_hb_debug_msg<0> (const char *what HB_UNUSED,
+ const void *obj HB_UNUSED,
+ const char *func HB_UNUSED,
+ bool indented HB_UNUSED,
+ unsigned int level HB_UNUSED,
+ int level_dir HB_UNUSED,
+ const char *message HB_UNUSED,
+ ...) {}
+
+#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
+#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, false, 0, 0, __VA_ARGS__)
+#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
+
+
+/*
+ * Printer
+ */
+
+template <typename T>
+struct hb_printer_t {};
+
+template <>
+struct hb_printer_t<bool> {
+ const char *print (bool v) { return v ? "true" : "false"; }
+};
+
+template <>
+struct hb_printer_t<hb_void_t> {
+ const char *print (hb_void_t) { return ""; }
+};
+
+
+/*
+ * Trace
+ */
+
+template <typename T>
+static inline void _hb_warn_no_return (bool returned)
+{
+ if (unlikely (!returned)) {
+ fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report.\n");
+ }
+}
+template <>
+inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
+{}
+
+template <int max_level, typename ret_t>
+struct hb_auto_trace_t {
+ explicit inline hb_auto_trace_t (unsigned int *plevel_,
+ const char *what_,
+ const void *obj_,
+ const char *func,
+ const char *message,
+ ...) : plevel (plevel_), what (what_), obj (obj_), returned (false)
+ {
+ if (plevel) ++*plevel;
+
+ va_list ap;
+ va_start (ap, message);
+ _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
+ va_end (ap);
+ }
+ inline ~hb_auto_trace_t (void)
+ {
+ _hb_warn_no_return<ret_t> (returned);
+ if (!returned) {
+ _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
+ }
+ if (plevel) --*plevel;
+ }
+
+ inline ret_t ret (ret_t v, unsigned int line = 0)
+ {
+ if (unlikely (returned)) {
+ fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, please report.\n");
+ return v;
+ }
+
+ _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
+ "return %s (line %d)",
+ hb_printer_t<ret_t>().print (v), line);
+ if (plevel) --*plevel;
+ plevel = NULL;
+ returned = true;
+ return v;
+ }
+
+ private:
+ unsigned int *plevel;
+ const char *what;
+ const void *obj;
+ bool returned;
+};
+template <typename ret_t> /* Optimize when tracing is disabled */
+struct hb_auto_trace_t<0, ret_t> {
+ explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
+ const char *what HB_UNUSED,
+ const void *obj HB_UNUSED,
+ const char *func HB_UNUSED,
+ const char *message HB_UNUSED,
+ ...) {}
+
+ inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
+};
+
+#define TRACE_RETURN(RET) trace.ret (RET, __LINE__)
+
+/* Misc */
+
+
+/* Pre-mature optimization:
+ * Checks for lo <= u <= hi but with an optimization if lo and hi
+ * are only different in a contiguous set of lower-most bits.
+ */
+template <typename T> static inline bool
+hb_in_range (T u, T lo, T hi)
+{
+ if ( ((lo^hi) & lo) == 0 &&
+ ((lo^hi) & hi) == (lo^hi) &&
+ ((lo^hi) & ((lo^hi) + 1)) == 0 )
+ return (u & ~(lo^hi)) == lo;
+ else
+ return lo <= u && u <= hi;
+}
+
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
+{
+ return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
+}
+
+
+/* Useful for set-operations on small enums.
+ * For example, for testing "x ∈ {x1, x2, x3}" use:
+ * (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
+ */
+#define FLAG(x) (1<<(x))
+#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
+
+
+template <typename T, typename T2> inline void
+hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
+{
+ if (unlikely (!len))
+ return;
+
+ unsigned int k = len - 1;
+ do {
+ unsigned int new_k = 0;
+
+ for (unsigned int j = 0; j < k; j++)
+ if (compar (&array[j], &array[j+1]) > 0)
+ {
+ {
+ T t;
+ t = array[j];
+ array[j] = array[j + 1];
+ array[j + 1] = t;
+ }
+ if (array2)
+ {
+ T2 t;
+ t = array2[j];
+ array2[j] = array2[j + 1];
+ array2[j + 1] = t;
+ }
+
+ new_k = j;
+ }
+ k = new_k;
+ } while (k);
+}
+
+template <typename T> inline void
+hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
+{
+ hb_bubble_sort (array, len, compar, (int *) NULL);
+}
+
+static inline hb_bool_t
+hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
+{
+ /* Pain because we don't know whether s is nul-terminated. */
+ char buf[64];
+ len = MIN (ARRAY_LENGTH (buf) - 1, len);
+ strncpy (buf, s, len);
+ buf[len] = '\0';
+
+ char *end;
+ errno = 0;
+ unsigned long v = strtoul (buf, &end, base);
+ if (errno) return false;
+ if (*end) return false;
+ *out = v;
+ return true;
+}
+
+
+/* Global runtime options. */
+
+struct hb_options_t
+{
+ int initialized : 1;
+ int uniscribe_bug_compatible : 1;
+};
+
+union hb_options_union_t {
+ int i;
+ hb_options_t opts;
+};
+ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t));
+
+HB_INTERNAL void
+_hb_options_init (void);
+
+extern HB_INTERNAL hb_options_union_t _hb_options;
+
+static inline hb_options_t
+hb_options (void)
+{
+ if (unlikely (!_hb_options.i))
+ _hb_options_init ();
+
+ return _hb_options.opts;
+}
+
+
+#endif /* HB_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
new file mode 100644
index 0000000000..adfa88f18e
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
@@ -0,0 +1,335 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SET_PRIVATE_HH
+#define HB_SET_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-set.h"
+#include "hb-object-private.hh"
+
+
+/*
+ * The set digests here implement various "filters" that support
+ * "approximate member query". Conceptually these are like Bloom
+ * Filter and Quotient Filter, however, much smaller, faster, and
+ * designed to fit the requirements of our uses for glyph coverage
+ * queries. As a result, our filters have much higher.
+ */
+
+template <typename mask_t, unsigned int shift>
+struct hb_set_digest_lowest_bits_t
+{
+ ASSERT_POD ();
+
+ static const unsigned int mask_bytes = sizeof (mask_t);
+ static const unsigned int mask_bits = sizeof (mask_t) * 8;
+ static const unsigned int num_bits = 0
+ + (mask_bytes >= 1 ? 3 : 0)
+ + (mask_bytes >= 2 ? 1 : 0)
+ + (mask_bytes >= 4 ? 1 : 0)
+ + (mask_bytes >= 8 ? 1 : 0)
+ + (mask_bytes >= 16? 1 : 0)
+ + 0;
+
+ ASSERT_STATIC (shift < sizeof (hb_codepoint_t) * 8);
+ ASSERT_STATIC (shift + num_bits <= sizeof (hb_codepoint_t) * 8);
+
+ inline void init (void) {
+ mask = 0;
+ }
+
+ inline void add (hb_codepoint_t g) {
+ mask |= mask_for (g);
+ }
+
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
+ if ((b >> shift) - (a >> shift) >= mask_bits - 1)
+ mask = (mask_t) -1;
+ else {
+ mask_t ma = mask_for (a);
+ mask_t mb = mask_for (b);
+ mask |= mb + (mb - ma) - (mb < ma);
+ }
+ }
+
+ inline bool may_have (hb_codepoint_t g) const {
+ return !!(mask & mask_for (g));
+ }
+
+ private:
+
+ static inline mask_t mask_for (hb_codepoint_t g) {
+ return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1));
+ }
+ mask_t mask;
+};
+
+template <typename head_t, typename tail_t>
+struct hb_set_digest_combiner_t
+{
+ ASSERT_POD ();
+
+ inline void init (void) {
+ head.init ();
+ tail.init ();
+ }
+
+ inline void add (hb_codepoint_t g) {
+ head.add (g);
+ tail.add (g);
+ }
+
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
+ head.add_range (a, b);
+ tail.add_range (a, b);
+ }
+
+ inline bool may_have (hb_codepoint_t g) const {
+ return head.may_have (g) && tail.may_have (g);
+ }
+
+ private:
+ head_t head;
+ tail_t tail;
+};
+
+
+/*
+ * hb_set_digest_t
+ *
+ * This is a combination of digests that performs "best".
+ * There is not much science to this: it's a result of intuition
+ * and testing.
+ */
+typedef hb_set_digest_combiner_t
+<
+ hb_set_digest_lowest_bits_t<unsigned long, 4>,
+ hb_set_digest_combiner_t
+ <
+ hb_set_digest_lowest_bits_t<unsigned long, 0>,
+ hb_set_digest_lowest_bits_t<unsigned long, 9>
+ >
+> hb_set_digest_t;
+
+
+
+/*
+ * hb_set_t
+ */
+
+
+/* TODO Make this faster and memmory efficient. */
+
+struct hb_set_t
+{
+ hb_object_header_t header;
+ ASSERT_POD ();
+ bool in_error;
+
+ inline void init (void) {
+ header.init ();
+ clear ();
+ }
+ inline void fini (void) {
+ }
+ inline void clear (void) {
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+ in_error = false;
+ memset (elts, 0, sizeof elts);
+ }
+ inline bool is_empty (void) const {
+ for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
+ if (elts[i])
+ return false;
+ return true;
+ }
+ inline void add (hb_codepoint_t g)
+ {
+ if (unlikely (in_error)) return;
+ if (unlikely (g == SENTINEL)) return;
+ if (unlikely (g > MAX_G)) return;
+ elt (g) |= mask (g);
+ }
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
+ {
+ if (unlikely (in_error)) return;
+ /* TODO Speedup */
+ for (unsigned int i = a; i < b + 1; i++)
+ add (i);
+ }
+ inline void del (hb_codepoint_t g)
+ {
+ if (unlikely (in_error)) return;
+ if (unlikely (g > MAX_G)) return;
+ elt (g) &= ~mask (g);
+ }
+ inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
+ {
+ if (unlikely (in_error)) return;
+ /* TODO Speedup */
+ for (unsigned int i = a; i < b + 1; i++)
+ del (i);
+ }
+ inline bool has (hb_codepoint_t g) const
+ {
+ if (unlikely (g > MAX_G)) return false;
+ return !!(elt (g) & mask (g));
+ }
+ inline bool intersects (hb_codepoint_t first,
+ hb_codepoint_t last) const
+ {
+ if (unlikely (first > MAX_G)) return false;
+ if (unlikely (last > MAX_G)) last = MAX_G;
+ unsigned int end = last + 1;
+ for (hb_codepoint_t i = first; i < end; i++)
+ if (has (i))
+ return true;
+ return false;
+ }
+ inline bool is_equal (const hb_set_t *other) const
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ if (elts[i] != other->elts[i])
+ return false;
+ return true;
+ }
+ inline void set (const hb_set_t *other)
+ {
+ if (unlikely (in_error)) return;
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] = other->elts[i];
+ }
+ inline void union_ (const hb_set_t *other)
+ {
+ if (unlikely (in_error)) return;
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] |= other->elts[i];
+ }
+ inline void intersect (const hb_set_t *other)
+ {
+ if (unlikely (in_error)) return;
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] &= other->elts[i];
+ }
+ inline void subtract (const hb_set_t *other)
+ {
+ if (unlikely (in_error)) return;
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] &= ~other->elts[i];
+ }
+ inline void symmetric_difference (const hb_set_t *other)
+ {
+ if (unlikely (in_error)) return;
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] ^= other->elts[i];
+ }
+ inline void invert (void)
+ {
+ if (unlikely (in_error)) return;
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] = ~elts[i];
+ }
+ inline bool next (hb_codepoint_t *codepoint) const
+ {
+ if (unlikely (*codepoint == SENTINEL)) {
+ hb_codepoint_t i = get_min ();
+ if (i != SENTINEL) {
+ *codepoint = i;
+ return true;
+ } else
+ return false;
+ }
+ for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
+ if (has (i)) {
+ *codepoint = i;
+ return true;
+ }
+ return false;
+ }
+ inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
+ {
+ hb_codepoint_t i;
+
+ i = *last;
+ if (!next (&i))
+ return false;
+
+ *last = *first = i;
+ while (next (&i) && i == *last + 1)
+ (*last)++;
+
+ return true;
+ }
+
+ inline unsigned int get_population (void) const
+ {
+ unsigned int count = 0;
+ for (unsigned int i = 0; i < ELTS; i++)
+ count += _hb_popcount32 (elts[i]);
+ return count;
+ }
+ inline hb_codepoint_t get_min (void) const
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ if (elts[i])
+ for (unsigned int j = 0; j < BITS; j++)
+ if (elts[i] & (1 << j))
+ return i * BITS + j;
+ return SENTINEL;
+ }
+ inline hb_codepoint_t get_max (void) const
+ {
+ for (unsigned int i = ELTS; i; i--)
+ if (elts[i - 1])
+ for (unsigned int j = BITS; j; j--)
+ if (elts[i - 1] & (1 << (j - 1)))
+ return (i - 1) * BITS + (j - 1);
+ return SENTINEL;
+ }
+
+ typedef uint32_t elt_t;
+ static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */
+ static const unsigned int SHIFT = 5;
+ static const unsigned int BITS = (1 << SHIFT);
+ static const unsigned int MASK = BITS - 1;
+ static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
+ static const hb_codepoint_t SENTINEL = (hb_codepoint_t) -1;
+
+ elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
+ elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
+ elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
+
+ elt_t elts[ELTS]; /* XXX 8kb */
+
+ ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
+ ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G);
+};
+
+
+
+#endif /* HB_SET_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.cc b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
new file mode 100644
index 0000000000..3c9573fbce
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
@@ -0,0 +1,227 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-set-private.hh"
+
+
+/* Public API */
+
+
+hb_set_t *
+hb_set_create (void)
+{
+ hb_set_t *set;
+
+ if (!(set = hb_object_create<hb_set_t> ()))
+ return hb_set_get_empty ();
+
+ set->clear ();
+
+ return set;
+}
+
+hb_set_t *
+hb_set_get_empty (void)
+{
+ static const hb_set_t _hb_set_nil = {
+ HB_OBJECT_HEADER_STATIC,
+ true, /* in_error */
+
+ {0} /* elts */
+ };
+
+ return const_cast<hb_set_t *> (&_hb_set_nil);
+}
+
+hb_set_t *
+hb_set_reference (hb_set_t *set)
+{
+ return hb_object_reference (set);
+}
+
+void
+hb_set_destroy (hb_set_t *set)
+{
+ if (!hb_object_destroy (set)) return;
+
+ set->fini ();
+
+ free (set);
+}
+
+hb_bool_t
+hb_set_set_user_data (hb_set_t *set,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (set, key, data, destroy, replace);
+}
+
+void *
+hb_set_get_user_data (hb_set_t *set,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (set, key);
+}
+
+
+hb_bool_t
+hb_set_allocation_successful (const hb_set_t *set HB_UNUSED)
+{
+ return !set->in_error;
+}
+
+void
+hb_set_clear (hb_set_t *set)
+{
+ set->clear ();
+}
+
+hb_bool_t
+hb_set_is_empty (const hb_set_t *set)
+{
+ return set->is_empty ();
+}
+
+hb_bool_t
+hb_set_has (const hb_set_t *set,
+ hb_codepoint_t codepoint)
+{
+ return set->has (codepoint);
+}
+
+void
+hb_set_add (hb_set_t *set,
+ hb_codepoint_t codepoint)
+{
+ set->add (codepoint);
+}
+
+void
+hb_set_add_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last)
+{
+ set->add_range (first, last);
+}
+
+void
+hb_set_del (hb_set_t *set,
+ hb_codepoint_t codepoint)
+{
+ set->del (codepoint);
+}
+
+void
+hb_set_del_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last)
+{
+ set->del_range (first, last);
+}
+
+hb_bool_t
+hb_set_is_equal (const hb_set_t *set,
+ const hb_set_t *other)
+{
+ return set->is_equal (other);
+}
+
+void
+hb_set_set (hb_set_t *set,
+ const hb_set_t *other)
+{
+ set->set (other);
+}
+
+void
+hb_set_union (hb_set_t *set,
+ const hb_set_t *other)
+{
+ set->union_ (other);
+}
+
+void
+hb_set_intersect (hb_set_t *set,
+ const hb_set_t *other)
+{
+ set->intersect (other);
+}
+
+void
+hb_set_subtract (hb_set_t *set,
+ const hb_set_t *other)
+{
+ set->subtract (other);
+}
+
+void
+hb_set_symmetric_difference (hb_set_t *set,
+ const hb_set_t *other)
+{
+ set->symmetric_difference (other);
+}
+
+void
+hb_set_invert (hb_set_t *set)
+{
+ set->invert ();
+}
+
+unsigned int
+hb_set_get_population (const hb_set_t *set)
+{
+ return set->get_population ();
+}
+
+hb_codepoint_t
+hb_set_get_min (const hb_set_t *set)
+{
+ return set->get_min ();
+}
+
+hb_codepoint_t
+hb_set_get_max (const hb_set_t *set)
+{
+ return set->get_max ();
+}
+
+hb_bool_t
+hb_set_next (const hb_set_t *set,
+ hb_codepoint_t *codepoint)
+{
+ return set->next (codepoint);
+}
+
+hb_bool_t
+hb_set_next_range (const hb_set_t *set,
+ hb_codepoint_t *first,
+ hb_codepoint_t *last)
+{
+ return set->next_range (first, last);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h
new file mode 100644
index 0000000000..291e24974e
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_SET_H
+#define HB_SET_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct hb_set_t hb_set_t;
+
+
+hb_set_t *
+hb_set_create (void);
+
+hb_set_t *
+hb_set_get_empty (void);
+
+hb_set_t *
+hb_set_reference (hb_set_t *set);
+
+void
+hb_set_destroy (hb_set_t *set);
+
+hb_bool_t
+hb_set_set_user_data (hb_set_t *set,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+void *
+hb_set_get_user_data (hb_set_t *set,
+ hb_user_data_key_t *key);
+
+
+/* Returns false if allocation has failed before */
+hb_bool_t
+hb_set_allocation_successful (const hb_set_t *set);
+
+void
+hb_set_clear (hb_set_t *set);
+
+hb_bool_t
+hb_set_is_empty (const hb_set_t *set);
+
+hb_bool_t
+hb_set_has (const hb_set_t *set,
+ hb_codepoint_t codepoint);
+
+/* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1
+ * which we will use as a sentinel. */
+void
+hb_set_add (hb_set_t *set,
+ hb_codepoint_t codepoint);
+
+void
+hb_set_add_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last);
+
+void
+hb_set_del (hb_set_t *set,
+ hb_codepoint_t codepoint);
+
+void
+hb_set_del_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last);
+
+hb_bool_t
+hb_set_is_equal (const hb_set_t *set,
+ const hb_set_t *other);
+
+void
+hb_set_set (hb_set_t *set,
+ const hb_set_t *other);
+
+void
+hb_set_union (hb_set_t *set,
+ const hb_set_t *other);
+
+void
+hb_set_intersect (hb_set_t *set,
+ const hb_set_t *other);
+
+void
+hb_set_subtract (hb_set_t *set,
+ const hb_set_t *other);
+
+void
+hb_set_symmetric_difference (hb_set_t *set,
+ const hb_set_t *other);
+
+void
+hb_set_invert (hb_set_t *set);
+
+unsigned int
+hb_set_get_population (const hb_set_t *set);
+
+/* Returns -1 if set empty. */
+hb_codepoint_t
+hb_set_get_min (const hb_set_t *set);
+
+/* Returns -1 if set empty. */
+hb_codepoint_t
+hb_set_get_max (const hb_set_t *set);
+
+/* Pass -1 in to get started. */
+hb_bool_t
+hb_set_next (const hb_set_t *set,
+ hb_codepoint_t *codepoint);
+
+/* Pass -1 for first and last to get started. */
+hb_bool_t
+hb_set_next_range (const hb_set_t *set,
+ hb_codepoint_t *first,
+ hb_codepoint_t *last);
+
+
+HB_END_DECLS
+
+#endif /* HB_SET_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
new file mode 100644
index 0000000000..dd014e38d0
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPE_PLAN_PRIVATE_HH
+#define HB_SHAPE_PLAN_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-shape-plan.h"
+#include "hb-object-private.hh"
+#include "hb-shaper-private.hh"
+
+
+struct hb_shape_plan_t
+{
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_bool_t default_shaper_list;
+ hb_face_t *face;
+ hb_segment_properties_t props;
+
+ hb_shape_func_t *shaper_func;
+ const char *shaper_name;
+
+ struct hb_shaper_data_t shaper_data;
+};
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \
+ , const hb_feature_t *user_features \
+ , unsigned int num_user_features
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+
+
+#endif /* HB_SHAPE_PLAN_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
new file mode 100644
index 0000000000..a6d2d26210
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
@@ -0,0 +1,314 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-shape-plan-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
+ HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+
+static void
+hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list)
+{
+ const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+
+#define HB_SHAPER_PLAN(shaper) \
+ HB_STMT_START { \
+ if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
+ HB_SHAPER_DATA (shaper, shape_plan) = \
+ HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
+ shape_plan->shaper_func = _hb_##shaper##_shape; \
+ shape_plan->shaper_name = #shaper; \
+ return; \
+ } \
+ } HB_STMT_END
+
+ if (likely (!shaper_list)) {
+ for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
+ if (0)
+ ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ else if (shapers[i].func == _hb_##shaper##_shape) \
+ HB_SHAPER_PLAN (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ } else {
+ for (; *shaper_list; shaper_list++)
+ if (0)
+ ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ else if (0 == strcmp (*shaper_list, #shaper)) \
+ HB_SHAPER_PLAN (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
+
+#undef HB_SHAPER_PLAN
+}
+
+
+/*
+ * hb_shape_plan_t
+ */
+
+hb_shape_plan_t *
+hb_shape_plan_create (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list)
+{
+ assert (props->direction != HB_DIRECTION_INVALID);
+
+ hb_shape_plan_t *shape_plan;
+
+ if (unlikely (!face))
+ face = hb_face_get_empty ();
+ if (unlikely (!props || hb_object_is_inert (face)))
+ return hb_shape_plan_get_empty ();
+ if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
+ return hb_shape_plan_get_empty ();
+
+ hb_face_make_immutable (face);
+ shape_plan->default_shaper_list = shaper_list == NULL;
+ shape_plan->face = hb_face_reference (face);
+ shape_plan->props = *props;
+
+ hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
+
+ return shape_plan;
+}
+
+hb_shape_plan_t *
+hb_shape_plan_get_empty (void)
+{
+ static const hb_shape_plan_t _hb_shape_plan_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* default_shaper_list */
+ NULL, /* face */
+ HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
+
+ NULL, /* shaper_func */
+ NULL, /* shaper_name */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
+ };
+
+ return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
+}
+
+hb_shape_plan_t *
+hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
+{
+ return hb_object_reference (shape_plan);
+}
+
+void
+hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
+{
+ if (!hb_object_destroy (shape_plan)) return;
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+ hb_face_destroy (shape_plan->face);
+
+ free (shape_plan);
+}
+
+hb_bool_t
+hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (shape_plan, key, data, destroy, replace);
+}
+
+void *
+hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (shape_plan, key);
+}
+
+
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ if (unlikely (hb_object_is_inert (shape_plan) ||
+ hb_object_is_inert (font) ||
+ hb_object_is_inert (buffer)))
+ return false;
+
+ assert (shape_plan->face == font->face);
+ assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
+
+#define HB_SHAPER_EXECUTE(shaper) \
+ HB_STMT_START { \
+ return HB_SHAPER_DATA (shaper, shape_plan) && \
+ hb_##shaper##_shaper_font_data_ensure (font) && \
+ _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
+ } HB_STMT_END
+
+ if (0)
+ ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ else if (shape_plan->shaper_func == _hb_##shaper##_shape) \
+ HB_SHAPER_EXECUTE (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+#undef HB_SHAPER_EXECUTE
+
+ return false;
+}
+
+
+/*
+ * caching
+ */
+
+#if 0
+static unsigned int
+hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
+{
+ return hb_segment_properties_hash (&shape_plan->props) +
+ shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_func;
+}
+#endif
+
+/* TODO no user-feature caching for now. */
+struct hb_shape_plan_proposal_t
+{
+ const hb_segment_properties_t props;
+ const char * const *shaper_list;
+ hb_shape_func_t *shaper_func;
+};
+
+static hb_bool_t
+hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
+ const hb_shape_plan_proposal_t *proposal)
+{
+ return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
+ ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
+ (shape_plan->shaper_func == proposal->shaper_func));
+}
+
+hb_shape_plan_t *
+hb_shape_plan_create_cached (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list)
+{
+ if (num_user_features)
+ return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+
+ hb_shape_plan_proposal_t proposal = {
+ *props,
+ shaper_list,
+ NULL
+ };
+
+ if (shaper_list) {
+ /* Choose shaper. Adapted from hb_shape_plan_plan(). */
+#define HB_SHAPER_PLAN(shaper) \
+ HB_STMT_START { \
+ if (hb_##shaper##_shaper_face_data_ensure (face)) \
+ proposal.shaper_func = _hb_##shaper##_shape; \
+ } HB_STMT_END
+
+ for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++)
+ if (0)
+ ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ else if (0 == strcmp (*shaper_item, #shaper)) \
+ HB_SHAPER_PLAN (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+#undef HB_SHAPER_PLAN
+
+ if (unlikely (!proposal.shaper_list))
+ return hb_shape_plan_get_empty ();
+ }
+
+
+retry:
+ hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atomic_ptr_get (&face->shape_plans);
+ for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
+ if (hb_shape_plan_matches (node->shape_plan, &proposal))
+ return hb_shape_plan_reference (node->shape_plan);
+
+ /* Not found. */
+
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+
+ hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
+ if (unlikely (!node))
+ return shape_plan;
+
+ node->shape_plan = shape_plan;
+ node->next = cached_plan_nodes;
+
+ if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
+ hb_shape_plan_destroy (shape_plan);
+ free (node);
+ goto retry;
+ }
+
+ /* Release our reference on face. */
+ hb_face_destroy (face);
+
+ return hb_shape_plan_reference (shape_plan);
+}
+
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
+{
+ return shape_plan->shaper_name;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h
new file mode 100644
index 0000000000..8f54552f90
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_SHAPE_PLAN_H
+#define HB_SHAPE_PLAN_H
+
+#include "hb-common.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+typedef struct hb_shape_plan_t hb_shape_plan_t;
+
+hb_shape_plan_t *
+hb_shape_plan_create (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list);
+
+hb_shape_plan_t *
+hb_shape_plan_create_cached (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list);
+
+hb_shape_plan_t *
+hb_shape_plan_get_empty (void);
+
+hb_shape_plan_t *
+hb_shape_plan_reference (hb_shape_plan_t *shape_plan);
+
+void
+hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
+
+hb_bool_t
+hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+void *
+hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key);
+
+
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features);
+
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan);
+
+
+HB_END_DECLS
+
+#endif /* HB_SHAPE_PLAN_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
new file mode 100644
index 0000000000..80d8c1306b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
@@ -0,0 +1,275 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+#include "hb-buffer-private.hh"
+#include "hb-font-private.hh"
+
+
+static void
+parse_space (const char **pp, const char *end)
+{
+ char c;
+ while (*pp < end && (c = **pp, ISSPACE (c)))
+ (*pp)++;
+}
+
+static hb_bool_t
+parse_char (const char **pp, const char *end, char c)
+{
+ parse_space (pp, end);
+
+ if (*pp == end || **pp != c)
+ return false;
+
+ (*pp)++;
+ return true;
+}
+
+static hb_bool_t
+parse_uint (const char **pp, const char *end, unsigned int *pv)
+{
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+ strncpy (buf, *pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ unsigned int v;
+
+ /* Intentionally use strtol instead of strtoul, such that
+ * -1 turns into "big number"... */
+ errno = 0;
+ v = strtol (p, &pend, 0);
+ if (errno || p == pend)
+ return false;
+
+ *pv = v;
+ *pp += pend - p;
+ return true;
+}
+
+static hb_bool_t
+parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
+{
+ if (parse_char (pp, end, '-'))
+ feature->value = 0;
+ else {
+ parse_char (pp, end, '+');
+ feature->value = 1;
+ }
+
+ return true;
+}
+
+static hb_bool_t
+parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature)
+{
+ const char *p = *pp;
+ char c;
+
+ parse_space (pp, end);
+
+#define ISALNUM(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '9'))
+ while (*pp < end && (c = **pp, ISALNUM(c)))
+ (*pp)++;
+#undef ISALNUM
+
+ if (p == *pp)
+ return false;
+
+ feature->tag = hb_tag_from_string (p, *pp - p);
+ return true;
+}
+
+static hb_bool_t
+parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
+{
+ parse_space (pp, end);
+
+ hb_bool_t has_start;
+
+ feature->start = 0;
+ feature->end = (unsigned int) -1;
+
+ if (!parse_char (pp, end, '['))
+ return true;
+
+ has_start = parse_uint (pp, end, &feature->start);
+
+ if (parse_char (pp, end, ':')) {
+ parse_uint (pp, end, &feature->end);
+ } else {
+ if (has_start)
+ feature->end = feature->start + 1;
+ }
+
+ return parse_char (pp, end, ']');
+}
+
+static hb_bool_t
+parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
+{
+ return !parse_char (pp, end, '=') || parse_uint (pp, end, &feature->value);
+}
+
+
+static hb_bool_t
+parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
+{
+ return parse_feature_value_prefix (pp, end, feature) &&
+ parse_feature_tag (pp, end, feature) &&
+ parse_feature_indices (pp, end, feature) &&
+ parse_feature_value_postfix (pp, end, feature) &&
+ *pp == end;
+}
+
+hb_bool_t
+hb_feature_from_string (const char *str, int len,
+ hb_feature_t *feature)
+{
+ if (len < 0)
+ len = strlen (str);
+
+ return parse_one_feature (&str, str + len, feature);
+}
+
+void
+hb_feature_to_string (hb_feature_t *feature,
+ char *buf, unsigned int size)
+{
+ if (unlikely (!size)) return;
+
+ char s[128];
+ unsigned int len = 0;
+ if (feature->value == 0)
+ s[len++] = '-';
+ hb_tag_to_string (feature->tag, s + len);
+ len += 4;
+ while (len && s[len - 1] == ' ')
+ len--;
+ if (feature->start != 0 || feature->end != (unsigned int) -1)
+ {
+ s[len++] = '[';
+ if (feature->start)
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->start));
+ if (feature->end != feature->start + 1) {
+ s[len++] = ':';
+ if (feature->end != (unsigned int) -1)
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->end));
+ }
+ s[len++] = ']';
+ }
+ if (feature->value > 1)
+ {
+ s[len++] = '=';
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->value));
+ }
+ assert (len < ARRAY_LENGTH (s));
+ len = MIN (len, size - 1);
+ memcpy (buf, s, len);
+ buf[len] = '\0';
+}
+
+
+static const char **static_shaper_list;
+
+static inline
+void free_static_shaper_list (void)
+{
+ free (static_shaper_list);
+}
+
+const char **
+hb_shape_list_shapers (void)
+{
+retry:
+ const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
+
+ if (unlikely (!shaper_list))
+ {
+ /* Not found; allocate one. */
+ shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
+ if (unlikely (!shaper_list)) {
+ static const char *nil_shaper_list[] = {NULL};
+ return nil_shaper_list;
+ }
+
+ const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+ unsigned int i;
+ for (i = 0; i < HB_SHAPERS_COUNT; i++)
+ shaper_list[i] = shapers[i].name;
+ shaper_list[i] = NULL;
+
+ if (!hb_atomic_ptr_cmpexch (&static_shaper_list, NULL, shaper_list)) {
+ free (shaper_list);
+ goto retry;
+ }
+
+#ifdef HAVE_ATEXIT
+ atexit (free_static_shaper_list); /* First person registers atexit() callback. */
+#endif
+ }
+
+ return shaper_list;
+}
+
+
+hb_bool_t
+hb_shape_full (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features,
+ const char * const *shaper_list)
+{
+ if (unlikely (!buffer->len))
+ return true;
+
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
+
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
+ hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
+ hb_shape_plan_destroy (shape_plan);
+
+ if (res)
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+ return res;
+}
+
+void
+hb_shape (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ hb_shape_full (font, buffer, features, num_features, NULL);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-shape.h
new file mode 100644
index 0000000000..10a35cb517
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_SHAPE_H
+#define HB_SHAPE_H
+
+#include "hb-common.h"
+#include "hb-buffer.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct hb_feature_t {
+ hb_tag_t tag;
+ uint32_t value;
+ unsigned int start;
+ unsigned int end;
+} hb_feature_t;
+
+/* len=-1 means str is NUL-terminated */
+hb_bool_t
+hb_feature_from_string (const char *str, int len,
+ hb_feature_t *feature);
+
+/* Something like 128 bytes is more than enough.
+ * nul-terminates. */
+void
+hb_feature_to_string (hb_feature_t *feature,
+ char *buf, unsigned int size);
+
+
+void
+hb_shape (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features);
+
+hb_bool_t
+hb_shape_full (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features,
+ const char * const *shaper_list);
+
+const char **
+hb_shape_list_shapers (void);
+
+
+HB_END_DECLS
+
+#endif /* HB_SHAPE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh
new file mode 100644
index 0000000000..7844081e95
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPER_IMPL_PRIVATE_HH
+#define HB_SHAPER_IMPL_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+
+
+#ifdef HB_SHAPER
+#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object)
+#endif
+
+
+#endif /* HB_SHAPER_IMPL_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
new file mode 100644
index 0000000000..b9c029e58f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPER_LIST_HH
+#define HB_SHAPER_LIST_HH
+#endif /* HB_SHAPER_LIST_HH */ /* Dummy header guards */
+
+/* v--- Add new shapers in the right place here. */
+
+#ifdef HAVE_GRAPHITE2
+/* Only picks up fonts that have a "Silf" table. */
+HB_SHAPER_IMPLEMENT (graphite2)
+#endif
+
+#ifdef HAVE_OT
+HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
+#endif
+
+#ifdef HAVE_HB_OLD
+HB_SHAPER_IMPLEMENT (old)
+#endif
+#ifdef HAVE_ICU_LE
+HB_SHAPER_IMPLEMENT (icu_le)
+#endif
+#ifdef HAVE_UNISCRIBE
+HB_SHAPER_IMPLEMENT (uniscribe)
+#endif
+#ifdef HAVE_CORETEXT
+HB_SHAPER_IMPLEMENT (coretext)
+#endif
+
+HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
new file mode 100644
index 0000000000..29c4493943
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPER_PRIVATE_HH
+#define HB_SHAPER_PRIVATE_HH
+
+#include "hb-private.hh"
+
+typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features);
+
+#define HB_SHAPER_IMPLEMENT(name) \
+ extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+struct hb_shaper_pair_t {
+ char name[16];
+ hb_shape_func_t *func;
+};
+
+HB_INTERNAL const hb_shaper_pair_t *
+_hb_shapers_get (void);
+
+
+/* For embedding in face / font / ... */
+struct hb_shaper_data_t {
+#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+
+#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
+
+/* Means: succeeded, but don't need to keep any data. */
+#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
+
+/* Means: tried but failed to create. */
+#define HB_SHAPER_DATA_INVALID ((void *) -1)
+#define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID)
+
+#define HB_SHAPER_DATA_TYPE(shaper, object) struct hb_##shaper##_shaper_##object##_data_t
+#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper)
+#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE (shaper, object, object)
+#define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create
+#define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy
+
+#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
+ HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
+ extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
+ HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
+ extern "C" HB_INTERNAL void \
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
+
+#define HB_SHAPER_DATA_DESTROY(shaper, object) \
+ if (object->shaper_data.shaper && \
+ object->shaper_data.shaper != HB_SHAPER_DATA_INVALID && \
+ object->shaper_data.shaper != HB_SHAPER_DATA_SUCCEEDED) \
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA (shaper, object));
+
+#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
+static inline bool \
+hb_##shaper##_shaper_##object##_data_ensure (hb_##object##_t *object) \
+{\
+ retry: \
+ HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
+ if (unlikely (!data)) { \
+ data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
+ if (unlikely (!data)) \
+ data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
+ if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \
+ if (data && \
+ data != HB_SHAPER_DATA_INVALID && \
+ data != HB_SHAPER_DATA_SUCCEEDED) \
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
+ goto retry; \
+ } \
+ } \
+ return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \
+}
+
+
+#endif /* HB_SHAPER_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
new file mode 100644
index 0000000000..44f718aa70
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-atomic-private.hh"
+
+
+static const hb_shaper_pair_t all_shapers[] = {
+#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+
+
+/* Thread-safe, lock-free, shapers */
+
+static const hb_shaper_pair_t *static_shapers;
+
+static inline
+void free_static_shapers (void)
+{
+ if (unlikely (static_shapers != all_shapers))
+ free ((void *) static_shapers);
+}
+
+const hb_shaper_pair_t *
+_hb_shapers_get (void)
+{
+retry:
+ hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
+
+ if (unlikely (!shapers))
+ {
+ char *env = getenv ("HB_SHAPER_LIST");
+ if (!env || !*env) {
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+ return (const hb_shaper_pair_t *) all_shapers;
+ }
+
+ /* Not found; allocate one. */
+ shapers = (hb_shaper_pair_t *) malloc (sizeof (all_shapers));
+ if (unlikely (!shapers)) {
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+ return (const hb_shaper_pair_t *) all_shapers;
+ }
+
+ memcpy (shapers, all_shapers, sizeof (all_shapers));
+
+ /* Reorder shaper list to prefer requested shapers. */
+ unsigned int i = 0;
+ char *end, *p = env;
+ for (;;) {
+ end = strchr (p, ',');
+ if (!end)
+ end = p + strlen (p);
+
+ for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
+ if (end - p == (int) strlen (shapers[j].name) &&
+ 0 == strncmp (shapers[j].name, p, end - p))
+ {
+ /* Reorder this shaper to position i */
+ struct hb_shaper_pair_t t = shapers[j];
+ memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
+ shapers[i] = t;
+ i++;
+ }
+
+ if (!*end)
+ break;
+ else
+ p = end + 1;
+ }
+
+ if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
+ free (shapers);
+ goto retry;
+ }
+
+#ifdef HAVE_ATEXIT
+ atexit (free_static_shapers); /* First person registers atexit() callback. */
+#endif
+ }
+
+ return shapers;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
new file mode 100644
index 0000000000..dd4d00138e
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
@@ -0,0 +1,317 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2011 Codethink Limited
+ * Copyright © 2010,2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_UNICODE_PRIVATE_HH
+#define HB_UNICODE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-unicode.h"
+#include "hb-object-private.hh"
+
+
+extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
+ HB_UNICODE_FUNC_IMPLEMENT (combining_class) \
+ HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \
+ HB_UNICODE_FUNC_IMPLEMENT (general_category) \
+ HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
+ HB_UNICODE_FUNC_IMPLEMENT (script) \
+ HB_UNICODE_FUNC_IMPLEMENT (compose) \
+ HB_UNICODE_FUNC_IMPLEMENT (decompose) \
+ HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \
+ /* ^--- Add new callbacks here */
+
+/* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
+#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \
+ HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_combining_class_t, combining_class) \
+ HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \
+ HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \
+ HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \
+ HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \
+ /* ^--- Add new simple callbacks here */
+
+struct hb_unicode_funcs_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_unicode_funcs_t *parent;
+
+ bool immutable;
+
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
+ inline return_type name (hb_codepoint_t unicode) { return func.name (this, unicode, user_data.name); }
+HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+ inline hb_bool_t compose (hb_codepoint_t a, hb_codepoint_t b,
+ hb_codepoint_t *ab)
+ {
+ *ab = 0;
+ if (unlikely (!a || !b)) return false;
+ return func.compose (this, a, b, ab, user_data.compose);
+ }
+
+ inline hb_bool_t decompose (hb_codepoint_t ab,
+ hb_codepoint_t *a, hb_codepoint_t *b)
+ {
+ *a = ab; *b = 0;
+ return func.decompose (this, ab, a, b, user_data.decompose);
+ }
+
+ inline unsigned int decompose_compatibility (hb_codepoint_t u,
+ hb_codepoint_t *decomposed)
+ {
+ unsigned int ret = func.decompose_compatibility (this, u, decomposed, user_data.decompose_compatibility);
+ if (ret == 1 && u == decomposed[0]) {
+ decomposed[0] = 0;
+ return 0;
+ }
+ decomposed[ret] = 0;
+ return ret;
+ }
+
+
+ unsigned int
+ modified_combining_class (hb_codepoint_t unicode)
+ {
+ /* XXX This hack belongs to the Myanmar shaper. */
+ if (unicode == 0x1037) unicode = 0x103A;
+
+ return _hb_modified_combining_class[combining_class (unicode)];
+ }
+
+ inline hb_bool_t
+ is_variation_selector (hb_codepoint_t unicode)
+ {
+ return unlikely (hb_in_ranges<hb_codepoint_t> (unicode,
+ 0x180B, 0x180D, /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */
+ 0xFE00, 0xFE0F, /* VARIATION SELECTOR-1..16 */
+ 0xE0100, 0xE01EF)); /* VARIATION SELECTOR-17..256 */
+ }
+
+ /* Default_Ignorable codepoints:
+ *
+ * Note that as of Oct 2012 (Unicode 6.2), U+180E MONGOLIAN VOWEL SEPARATOR
+ * is NOT Default_Ignorable, but it really behaves in a way that it should
+ * be. That has been reported to the Unicode Technical Committee for
+ * consideration. As such, we include it here, since Uniscribe removes it.
+ * It *is* in Unicode 6.3 however. U+061C ARABIC LETTER MARK from Unicode
+ * 6.3 is also added manually. The new Unicode 6.3 bidi formatting
+ * characters are encoded in a block that was Default_Ignorable already.
+ *
+ * Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to
+ * hide them, as the way Uniscribe has implemented them is with regular
+ * spacing glyphs, and that's the way fonts are made to work. As such,
+ * we make exceptions for those two.
+ *
+ * Gathered from:
+ * http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
+ *
+ * Last updated to the page with the following versions:
+ * Version 3.6; ICU version: 50.0.1.0; Unicode version: 6.1.0.0
+ *
+ * 4,167 Code Points
+ *
+ * [\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001D173-\U0001D17A\U000E0000-\U000E0FFF]
+ *
+ * 00AD ;SOFT HYPHEN
+ * 034F ;COMBINING GRAPHEME JOINER
+ * #115F ;HANGUL CHOSEONG FILLER
+ * #1160 ;HANGUL JUNGSEONG FILLER
+ * 17B4 ;KHMER VOWEL INHERENT AQ
+ * 17B5 ;KHMER VOWEL INHERENT AA
+ * 180B..180D ;MONGOLIAN FREE VARIATION SELECTOR THREE
+ * 200B..200F ;RIGHT-TO-LEFT MARK
+ * 202A..202E ;RIGHT-TO-LEFT OVERRIDE
+ * 2060..206F ;NOMINAL DIGIT SHAPES
+ * 3164 ;HANGUL FILLER
+ * FE00..FE0F ;VARIATION SELECTOR-16
+ * FEFF ;ZERO WIDTH NO-BREAK SPACE
+ * FFA0 ;HALFWIDTH HANGUL FILLER
+ * FFF0..FFF8 ;<unassigned-FFF8>
+ * 1D173..1D17A ;MUSICAL SYMBOL END PHRASE
+ * E0000..E0FFF ;<unassigned-E0FFF>
+ */
+ inline hb_bool_t
+ is_default_ignorable (hb_codepoint_t ch)
+ {
+ hb_codepoint_t plane = ch >> 16;
+ if (likely (plane == 0))
+ {
+ /* BMP */
+ hb_codepoint_t page = ch >> 8;
+ switch (page) {
+ case 0x00: return unlikely (ch == 0x00AD);
+ case 0x03: return unlikely (ch == 0x034F);
+ case 0x06: return unlikely (ch == 0x061C);
+ case 0x17: return hb_in_range<hb_codepoint_t> (ch, 0x17B4, 0x17B5);
+ case 0x18: return hb_in_range<hb_codepoint_t> (ch, 0x180B, 0x180E);
+ case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200B, 0x200F,
+ 0x202A, 0x202E,
+ 0x2060, 0x206F);
+ case 0x31: return unlikely (ch == 0x3164);
+ case 0xFE: return hb_in_range<hb_codepoint_t> (ch, 0xFE00, 0xFE0F) || ch == 0xFEFF;
+ case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8) || ch == 0xFFA0;
+ default: return false;
+ }
+ }
+ else
+ {
+ /* Other planes */
+ switch (plane) {
+ case 0x01: return hb_in_range<hb_codepoint_t> (ch, 0x0001D173, 0x0001D17A);
+ case 0x0E: return hb_in_range<hb_codepoint_t> (ch, 0x000E0000, 0x000E0FFF);
+ default: return false;
+ }
+ }
+ }
+
+
+ struct {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name;
+ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+ } func;
+
+ struct {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) void *name;
+ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+ } user_data;
+
+ struct {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+ } destroy;
+};
+
+
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
+
+
+/* Modified combining marks */
+
+/* Hebrew
+ *
+ * We permute the "fixed-position" classes 10-26 into the order
+ * described in the SBL Hebrew manual:
+ *
+ * http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
+ *
+ * (as recommended by:
+ * http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
+ *
+ * More details here:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=662055
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC10 22 /* sheva */
+#define HB_MODIFIED_COMBINING_CLASS_CCC11 15 /* hataf segol */
+#define HB_MODIFIED_COMBINING_CLASS_CCC12 16 /* hataf patah */
+#define HB_MODIFIED_COMBINING_CLASS_CCC13 17 /* hataf qamats */
+#define HB_MODIFIED_COMBINING_CLASS_CCC14 23 /* hiriq */
+#define HB_MODIFIED_COMBINING_CLASS_CCC15 18 /* tsere */
+#define HB_MODIFIED_COMBINING_CLASS_CCC16 19 /* segol */
+#define HB_MODIFIED_COMBINING_CLASS_CCC17 20 /* patah */
+#define HB_MODIFIED_COMBINING_CLASS_CCC18 21 /* qamats */
+#define HB_MODIFIED_COMBINING_CLASS_CCC19 14 /* holam */
+#define HB_MODIFIED_COMBINING_CLASS_CCC20 24 /* qubuts */
+#define HB_MODIFIED_COMBINING_CLASS_CCC21 12 /* dagesh */
+#define HB_MODIFIED_COMBINING_CLASS_CCC22 25 /* meteg */
+#define HB_MODIFIED_COMBINING_CLASS_CCC23 13 /* rafe */
+#define HB_MODIFIED_COMBINING_CLASS_CCC24 10 /* shin dot */
+#define HB_MODIFIED_COMBINING_CLASS_CCC25 11 /* sin dot */
+#define HB_MODIFIED_COMBINING_CLASS_CCC26 26 /* point varika */
+
+/*
+ * Arabic
+ *
+ * Modify to move Shadda (ccc=33) before other marks. See:
+ * http://unicode.org/faq/normalization.html#8
+ * http://unicode.org/faq/normalization.html#9
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC27 28 /* fathatan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC28 29 /* dammatan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC29 30 /* kasratan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC30 31 /* fatha */
+#define HB_MODIFIED_COMBINING_CLASS_CCC31 32 /* damma */
+#define HB_MODIFIED_COMBINING_CLASS_CCC32 33 /* kasra */
+#define HB_MODIFIED_COMBINING_CLASS_CCC33 27 /* shadda */
+#define HB_MODIFIED_COMBINING_CLASS_CCC34 34 /* sukun */
+#define HB_MODIFIED_COMBINING_CLASS_CCC35 35 /* superscript alef */
+
+/* Syriac */
+#define HB_MODIFIED_COMBINING_CLASS_CCC36 36 /* superscript alaph */
+
+/* Telugu
+ *
+ * Modify Telugu length marks (ccc=84, ccc=91).
+ * These are the only matras in the main Indic scripts range that have
+ * a non-zero ccc. That makes them reorder with the Halant that is
+ * ccc=9. Just zero them, we don't need them in our Indic shaper.
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC84 0 /* length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC91 0 /* ai length mark */
+
+/* Thai
+ *
+ * Modify U+0E38 and U+0E39 (ccc=103) to be reordered before U+0E3A (ccc=9).
+ * Assign 3, which is unassigned otherwise.
+ * Uniscribe does this reordering too.
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC103 3 /* sara u / sara uu */
+#define HB_MODIFIED_COMBINING_CLASS_CCC107 107 /* mai * */
+
+/* Lao */
+#define HB_MODIFIED_COMBINING_CLASS_CCC118 118 /* sign u / sign uu */
+#define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */
+
+/* Tibetan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */
+#define HB_MODIFIED_COMBINING_CLASS_CCC130 130 /* sign i */
+#define HB_MODIFIED_COMBINING_CLASS_CCC132 132 /* sign u */
+
+
+/* Misc */
+
+#define HB_UNICODE_GENERAL_CATEGORY_IS_MARK(gen_cat) \
+ (FLAG (gen_cat) & \
+ (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
+
+
+#endif /* HB_UNICODE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
new file mode 100644
index 0000000000..b7e098737c
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
@@ -0,0 +1,435 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2011 Codethink Limited
+ * Copyright © 2010,2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-unicode-private.hh"
+
+
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+static hb_unicode_combining_class_t
+hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
+}
+
+static unsigned int
+hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return 1;
+}
+
+static hb_unicode_general_category_t
+hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
+}
+
+static hb_codepoint_t
+hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return unicode;
+}
+
+static hb_script_t
+hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return HB_SCRIPT_UNKNOWN;
+}
+
+static hb_bool_t
+hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t a HB_UNUSED,
+ hb_codepoint_t b HB_UNUSED,
+ hb_codepoint_t *ab HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return false;
+}
+
+static hb_bool_t
+hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t ab HB_UNUSED,
+ hb_codepoint_t *a HB_UNUSED,
+ hb_codepoint_t *b HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return false;
+}
+
+
+static unsigned int
+hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t u HB_UNUSED,
+ hb_codepoint_t *decomposed HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return 0;
+}
+
+
+#define HB_UNICODE_FUNCS_IMPLEMENT_SET \
+ HB_UNICODE_FUNCS_IMPLEMENT (glib) \
+ HB_UNICODE_FUNCS_IMPLEMENT (icu) \
+ HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \
+ HB_UNICODE_FUNCS_IMPLEMENT (nil) \
+ /* ^--- Add new callbacks before nil */
+
+#define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty
+
+/* Prototype them all */
+#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
+extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void);
+HB_UNICODE_FUNCS_IMPLEMENT_SET
+#undef HB_UNICODE_FUNCS_IMPLEMENT
+
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_default (void)
+{
+#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
+ return hb_##set##_get_unicode_funcs ();
+
+#ifdef HAVE_GLIB
+ HB_UNICODE_FUNCS_IMPLEMENT(glib)
+#elif 0 && defined(HAVE_ICU)
+ HB_UNICODE_FUNCS_IMPLEMENT(icu)
+#elif defined(HAVE_UCDN)
+ HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
+#else
+#define HB_UNICODE_FUNCS_NIL 1
+ HB_UNICODE_FUNCS_IMPLEMENT(nil)
+#endif
+
+#undef HB_UNICODE_FUNCS_IMPLEMENT
+}
+
+#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
+#pragma message("Could not find any Unicode functions implementation, you have to provide your own.")
+#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.")
+#endif
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
+{
+ hb_unicode_funcs_t *ufuncs;
+
+ if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
+ return hb_unicode_funcs_get_empty ();
+
+ if (!parent)
+ parent = hb_unicode_funcs_get_empty ();
+
+ hb_unicode_funcs_make_immutable (parent);
+ ufuncs->parent = hb_unicode_funcs_reference (parent);
+
+ ufuncs->func = parent->func;
+
+ /* We can safely copy user_data from parent since we hold a reference
+ * onto it and it's immutable. We should not copy the destroy notifiers
+ * though. */
+ ufuncs->user_data = parent->user_data;
+
+ return ufuncs;
+}
+
+
+const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ NULL, /* parent */
+ true, /* immutable */
+ {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
+ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+ }
+};
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_empty (void)
+{
+ return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
+}
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
+{
+ return hb_object_reference (ufuncs);
+}
+
+void
+hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
+{
+ if (!hb_object_destroy (ufuncs)) return;
+
+#define HB_UNICODE_FUNC_IMPLEMENT(name) \
+ if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
+ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+ hb_unicode_funcs_destroy (ufuncs->parent);
+
+ free (ufuncs);
+}
+
+hb_bool_t
+hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
+}
+
+void *
+hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (ufuncs, key);
+}
+
+
+void
+hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
+{
+ if (hb_object_is_inert (ufuncs))
+ return;
+
+ ufuncs->immutable = true;
+}
+
+hb_bool_t
+hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
+{
+ return ufuncs->immutable;
+}
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
+{
+ return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
+}
+
+
+#define HB_UNICODE_FUNC_IMPLEMENT(name) \
+ \
+void \
+hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
+ hb_unicode_##name##_func_t func, \
+ void *user_data, \
+ hb_destroy_func_t destroy) \
+{ \
+ if (ufuncs->immutable) \
+ return; \
+ \
+ if (ufuncs->destroy.name) \
+ ufuncs->destroy.name (ufuncs->user_data.name); \
+ \
+ if (func) { \
+ ufuncs->func.name = func; \
+ ufuncs->user_data.name = user_data; \
+ ufuncs->destroy.name = destroy; \
+ } else { \
+ ufuncs->func.name = ufuncs->parent->func.name; \
+ ufuncs->user_data.name = ufuncs->parent->user_data.name; \
+ ufuncs->destroy.name = NULL; \
+ } \
+}
+
+HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
+ \
+return_type \
+hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \
+ hb_codepoint_t unicode) \
+{ \
+ return ufuncs->name (unicode); \
+}
+HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+hb_bool_t
+hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
+{
+ return ufuncs->compose (a, b, ab);
+}
+
+hb_bool_t
+hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b)
+{
+ return ufuncs->decompose (ab, a, b);
+}
+
+unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed)
+{
+ return ufuncs->decompose_compatibility (u, decomposed);
+}
+
+
+/* See hb-unicode-private.hh for details. */
+const uint8_t
+_hb_modified_combining_class[256] =
+{
+ 0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */
+ 1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */
+ 2, 3, 4, 5, 6,
+ 7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */
+ 8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */
+ 9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */
+
+ /* Hebrew */
+ HB_MODIFIED_COMBINING_CLASS_CCC10,
+ HB_MODIFIED_COMBINING_CLASS_CCC11,
+ HB_MODIFIED_COMBINING_CLASS_CCC12,
+ HB_MODIFIED_COMBINING_CLASS_CCC13,
+ HB_MODIFIED_COMBINING_CLASS_CCC14,
+ HB_MODIFIED_COMBINING_CLASS_CCC15,
+ HB_MODIFIED_COMBINING_CLASS_CCC16,
+ HB_MODIFIED_COMBINING_CLASS_CCC17,
+ HB_MODIFIED_COMBINING_CLASS_CCC18,
+ HB_MODIFIED_COMBINING_CLASS_CCC19,
+ HB_MODIFIED_COMBINING_CLASS_CCC20,
+ HB_MODIFIED_COMBINING_CLASS_CCC21,
+ HB_MODIFIED_COMBINING_CLASS_CCC22,
+ HB_MODIFIED_COMBINING_CLASS_CCC23,
+ HB_MODIFIED_COMBINING_CLASS_CCC24,
+ HB_MODIFIED_COMBINING_CLASS_CCC25,
+ HB_MODIFIED_COMBINING_CLASS_CCC26,
+
+ /* Arabic */
+ HB_MODIFIED_COMBINING_CLASS_CCC27,
+ HB_MODIFIED_COMBINING_CLASS_CCC28,
+ HB_MODIFIED_COMBINING_CLASS_CCC29,
+ HB_MODIFIED_COMBINING_CLASS_CCC30,
+ HB_MODIFIED_COMBINING_CLASS_CCC31,
+ HB_MODIFIED_COMBINING_CLASS_CCC32,
+ HB_MODIFIED_COMBINING_CLASS_CCC33,
+ HB_MODIFIED_COMBINING_CLASS_CCC34,
+ HB_MODIFIED_COMBINING_CLASS_CCC35,
+
+ /* Syriac */
+ HB_MODIFIED_COMBINING_CLASS_CCC36,
+
+ 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83,
+
+ /* Telugu */
+ HB_MODIFIED_COMBINING_CLASS_CCC84,
+ 85, 86, 87, 88, 89, 90,
+ HB_MODIFIED_COMBINING_CLASS_CCC91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+
+ /* Thai */
+ HB_MODIFIED_COMBINING_CLASS_CCC103,
+ 104, 105, 106,
+ HB_MODIFIED_COMBINING_CLASS_CCC107,
+ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+
+ /* Lao */
+ HB_MODIFIED_COMBINING_CLASS_CCC118,
+ 119, 120, 121,
+ HB_MODIFIED_COMBINING_CLASS_CCC122,
+ 123, 124, 125, 126, 127, 128,
+
+ /* Tibetan */
+ HB_MODIFIED_COMBINING_CLASS_CCC129,
+ HB_MODIFIED_COMBINING_CLASS_CCC130,
+ 131,
+ HB_MODIFIED_COMBINING_CLASS_CCC132,
+ 133, 134, 135, 136, 137, 138, 139,
+
+
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+ 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
+
+ 200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */
+ 201,
+ 202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */
+ 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
+ 214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */
+ 215,
+ 216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */
+ 217,
+ 218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */
+ 219,
+ 220, /* HB_UNICODE_COMBINING_CLASS_BELOW */
+ 221,
+ 222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */
+ 223,
+ 224, /* HB_UNICODE_COMBINING_CLASS_LEFT */
+ 225,
+ 226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */
+ 227,
+ 228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */
+ 229,
+ 230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */
+ 231,
+ 232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */
+ 233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */
+ 234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */
+ 235, 236, 237, 238, 239,
+ 240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */
+ 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+ 255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
new file mode 100644
index 0000000000..2e10d98a3b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
@@ -0,0 +1,357 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2011 Codethink Limited
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_UNICODE_H
+#define HB_UNICODE_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+/* hb_unicode_general_category_t */
+
+/* Unicode Character Database property: General_Category (gc) */
+typedef enum
+{
+ HB_UNICODE_GENERAL_CATEGORY_CONTROL, /* Cc */
+ HB_UNICODE_GENERAL_CATEGORY_FORMAT, /* Cf */
+ HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED, /* Cn */
+ HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE, /* Co */
+ HB_UNICODE_GENERAL_CATEGORY_SURROGATE, /* Cs */
+ HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER, /* Ll */
+ HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER, /* Lm */
+ HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER, /* Lo */
+ HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER, /* Lt */
+ HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER, /* Lu */
+ HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK, /* Mc */
+ HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK, /* Me */
+ HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK, /* Mn */
+ HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER, /* Nd */
+ HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER, /* Nl */
+ HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER, /* No */
+ HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION, /* Pc */
+ HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION, /* Pd */
+ HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION, /* Pe */
+ HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION, /* Pf */
+ HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION, /* Pi */
+ HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION, /* Po */
+ HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION, /* Ps */
+ HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL, /* Sc */
+ HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL, /* Sk */
+ HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL, /* Sm */
+ HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL, /* So */
+ HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR, /* Zl */
+ HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR, /* Zp */
+ HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR /* Zs */
+} hb_unicode_general_category_t;
+
+/* hb_unicode_combining_class_t */
+
+/* Note: newer versions of Unicode may add new values. Clients should be ready to handle
+ * any value in the 0..254 range being returned from hb_unicode_combining_class().
+ */
+
+/* Unicode Character Database property: Canonical_Combining_Class (ccc) */
+typedef enum
+{
+ HB_UNICODE_COMBINING_CLASS_NOT_REORDERED = 0,
+ HB_UNICODE_COMBINING_CLASS_OVERLAY = 1,
+ HB_UNICODE_COMBINING_CLASS_NUKTA = 7,
+ HB_UNICODE_COMBINING_CLASS_KANA_VOICING = 8,
+ HB_UNICODE_COMBINING_CLASS_VIRAMA = 9,
+
+ /* Hebrew */
+ HB_UNICODE_COMBINING_CLASS_CCC10 = 10,
+ HB_UNICODE_COMBINING_CLASS_CCC11 = 11,
+ HB_UNICODE_COMBINING_CLASS_CCC12 = 12,
+ HB_UNICODE_COMBINING_CLASS_CCC13 = 13,
+ HB_UNICODE_COMBINING_CLASS_CCC14 = 14,
+ HB_UNICODE_COMBINING_CLASS_CCC15 = 15,
+ HB_UNICODE_COMBINING_CLASS_CCC16 = 16,
+ HB_UNICODE_COMBINING_CLASS_CCC17 = 17,
+ HB_UNICODE_COMBINING_CLASS_CCC18 = 18,
+ HB_UNICODE_COMBINING_CLASS_CCC19 = 19,
+ HB_UNICODE_COMBINING_CLASS_CCC20 = 20,
+ HB_UNICODE_COMBINING_CLASS_CCC21 = 21,
+ HB_UNICODE_COMBINING_CLASS_CCC22 = 22,
+ HB_UNICODE_COMBINING_CLASS_CCC23 = 23,
+ HB_UNICODE_COMBINING_CLASS_CCC24 = 24,
+ HB_UNICODE_COMBINING_CLASS_CCC25 = 25,
+ HB_UNICODE_COMBINING_CLASS_CCC26 = 26,
+
+ /* Arabic */
+ HB_UNICODE_COMBINING_CLASS_CCC27 = 27,
+ HB_UNICODE_COMBINING_CLASS_CCC28 = 28,
+ HB_UNICODE_COMBINING_CLASS_CCC29 = 29,
+ HB_UNICODE_COMBINING_CLASS_CCC30 = 30,
+ HB_UNICODE_COMBINING_CLASS_CCC31 = 31,
+ HB_UNICODE_COMBINING_CLASS_CCC32 = 32,
+ HB_UNICODE_COMBINING_CLASS_CCC33 = 33,
+ HB_UNICODE_COMBINING_CLASS_CCC34 = 34,
+ HB_UNICODE_COMBINING_CLASS_CCC35 = 35,
+
+ /* Syriac */
+ HB_UNICODE_COMBINING_CLASS_CCC36 = 36,
+
+ /* Telugu */
+ HB_UNICODE_COMBINING_CLASS_CCC84 = 84,
+ HB_UNICODE_COMBINING_CLASS_CCC91 = 91,
+
+ /* Thai */
+ HB_UNICODE_COMBINING_CLASS_CCC103 = 103,
+ HB_UNICODE_COMBINING_CLASS_CCC107 = 107,
+
+ /* Lao */
+ HB_UNICODE_COMBINING_CLASS_CCC118 = 118,
+ HB_UNICODE_COMBINING_CLASS_CCC122 = 122,
+
+ /* Tibetan */
+ HB_UNICODE_COMBINING_CLASS_CCC129 = 129,
+ HB_UNICODE_COMBINING_CLASS_CCC130 = 130,
+ HB_UNICODE_COMBINING_CLASS_CCC133 = 132,
+
+
+ HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT = 200,
+ HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW = 202,
+ HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE = 214,
+ HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT = 216,
+ HB_UNICODE_COMBINING_CLASS_BELOW_LEFT = 218,
+ HB_UNICODE_COMBINING_CLASS_BELOW = 220,
+ HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT = 222,
+ HB_UNICODE_COMBINING_CLASS_LEFT = 224,
+ HB_UNICODE_COMBINING_CLASS_RIGHT = 226,
+ HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT = 228,
+ HB_UNICODE_COMBINING_CLASS_ABOVE = 230,
+ HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT = 232,
+ HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW = 233,
+ HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE = 234,
+
+ HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT = 240,
+
+ HB_UNICODE_COMBINING_CLASS_INVALID = 255
+} hb_unicode_combining_class_t;
+
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+typedef struct hb_unicode_funcs_t hb_unicode_funcs_t;
+
+
+/*
+ * just give me the best implementation you've got there.
+ */
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_default (void);
+
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_create (hb_unicode_funcs_t *parent);
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_empty (void);
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs);
+
+void
+hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
+
+hb_bool_t
+hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+
+void *
+hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
+ hb_user_data_key_t *key);
+
+
+void
+hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs);
+
+hb_bool_t
+hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs);
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
+
+
+/*
+ * funcs
+ */
+
+/* typedefs */
+
+typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
+typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
+typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
+typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
+typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
+
+typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab,
+ void *user_data);
+typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b,
+ void *user_data);
+
+/**
+ * hb_unicode_decompose_compatibility_func_t:
+ * @ufuncs: Unicode function structure
+ * @u: codepoint to decompose
+ * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
+ * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
+ *
+ * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
+ * The complete length of the decomposition will be returned.
+ *
+ * If @u has no compatibility decomposition, zero should be returned.
+ *
+ * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
+ * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
+ * of this function type must ensure that they do not write past the provided array.
+ *
+ * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
+ */
+typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed,
+ void *user_data);
+
+/* See Unicode 6.1 for details on the maximum decomposition length. */
+#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
+
+/* setters */
+
+void
+hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_combining_class_func_t combining_class_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_eastasian_width_func_t eastasian_width_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_general_category_func_t general_category_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_mirroring_func_t mirroring_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_script_func_t script_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_compose_func_t compose_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_decompose_func_t decompose_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_decompose_compatibility_func_t decompose_compatibility_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+/* accessors */
+
+hb_unicode_combining_class_t
+hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+unsigned int
+hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+hb_unicode_general_category_t
+hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+hb_codepoint_t
+hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+hb_script_t
+hb_unicode_script (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+hb_bool_t
+hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab);
+hb_bool_t
+hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b);
+
+unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed);
+
+HB_END_DECLS
+
+#endif /* HB_UNICODE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
new file mode 100644
index 0000000000..b9a6519d28
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
@@ -0,0 +1,204 @@
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_UTF_PRIVATE_HH
+#define HB_UTF_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* UTF-8 */
+
+#define HB_UTF8_COMPUTE(Char, Mask, Len) \
+ if (Char < 128) { Len = 1; Mask = 0x7f; } \
+ else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
+ else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \
+ else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
+ else Len = 0;
+
+static inline const uint8_t *
+hb_utf_next (const uint8_t *text,
+ const uint8_t *end,
+ hb_codepoint_t *unicode)
+{
+ hb_codepoint_t c = *text, mask;
+ unsigned int len;
+
+ /* TODO check for overlong sequences? */
+
+ HB_UTF8_COMPUTE (c, mask, len);
+ if (unlikely (!len || (unsigned int) (end - text) < len)) {
+ *unicode = -1;
+ return text + 1;
+ } else {
+ hb_codepoint_t result;
+ unsigned int i;
+ result = c & mask;
+ for (i = 1; i < len; i++)
+ {
+ if (unlikely ((text[i] & 0xc0) != 0x80))
+ {
+ *unicode = -1;
+ return text + 1;
+ }
+ result <<= 6;
+ result |= (text[i] & 0x3f);
+ }
+ *unicode = result;
+ return text + len;
+ }
+}
+
+static inline const uint8_t *
+hb_utf_prev (const uint8_t *text,
+ const uint8_t *start,
+ hb_codepoint_t *unicode)
+{
+ const uint8_t *end = text--;
+ while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
+ text--;
+
+ hb_codepoint_t c = *text, mask;
+ unsigned int len;
+
+ /* TODO check for overlong sequences? */
+
+ HB_UTF8_COMPUTE (c, mask, len);
+ if (unlikely (!len || (unsigned int) (end - text) != len)) {
+ *unicode = -1;
+ return end - 1;
+ } else {
+ hb_codepoint_t result;
+ unsigned int i;
+ result = c & mask;
+ for (i = 1; i < len; i++)
+ {
+ result <<= 6;
+ result |= (text[i] & 0x3f);
+ }
+ *unicode = result;
+ return text;
+ }
+}
+
+
+static inline unsigned int
+hb_utf_strlen (const uint8_t *text)
+{
+ return strlen ((const char *) text);
+}
+
+
+/* UTF-16 */
+
+static inline const uint16_t *
+hb_utf_next (const uint16_t *text,
+ const uint16_t *end,
+ hb_codepoint_t *unicode)
+{
+ hb_codepoint_t c = *text++;
+
+ if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xd800, 0xdbff)))
+ {
+ /* high surrogate */
+ hb_codepoint_t l;
+ if (text < end && ((l = *text), likely (hb_in_range<hb_codepoint_t> (l, 0xdc00, 0xdfff))))
+ {
+ /* low surrogate */
+ *unicode = (c << 10) + l - ((0xd800 << 10) - 0x10000 + 0xdc00);
+ text++;
+ } else
+ *unicode = -1;
+ } else
+ *unicode = c;
+
+ return text;
+}
+
+static inline const uint16_t *
+hb_utf_prev (const uint16_t *text,
+ const uint16_t *start,
+ hb_codepoint_t *unicode)
+{
+ hb_codepoint_t c = *--text;
+
+ if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xdc00, 0xdfff)))
+ {
+ /* low surrogate */
+ hb_codepoint_t h;
+ if (start < text && ((h = *(text - 1)), likely (hb_in_range<hb_codepoint_t> (h, 0xd800, 0xdbff))))
+ {
+ /* high surrogate */
+ *unicode = (h << 10) + c - ((0xd800 << 10) - 0x10000 + 0xdc00);
+ text--;
+ } else
+ *unicode = -1;
+ } else
+ *unicode = c;
+
+ return text;
+}
+
+
+static inline unsigned int
+hb_utf_strlen (const uint16_t *text)
+{
+ unsigned int l = 0;
+ while (*text++) l++;
+ return l;
+}
+
+
+/* UTF-32 */
+
+static inline const uint32_t *
+hb_utf_next (const uint32_t *text,
+ const uint32_t *end HB_UNUSED,
+ hb_codepoint_t *unicode)
+{
+ *unicode = *text++;
+ return text;
+}
+
+static inline const uint32_t *
+hb_utf_prev (const uint32_t *text,
+ const uint32_t *start HB_UNUSED,
+ hb_codepoint_t *unicode)
+{
+ *unicode = *--text;
+ return text;
+}
+
+static inline unsigned int
+hb_utf_strlen (const uint32_t *text)
+{
+ unsigned int l = 0;
+ while (*text++) l++;
+ return l;
+}
+
+
+#endif /* HB_UTF_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h
new file mode 100644
index 0000000000..dc07ef794a
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2011 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_VERSION_H
+#define HB_VERSION_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+#define HB_VERSION_MAJOR 0
+#define HB_VERSION_MINOR 9
+#define HB_VERSION_MICRO 20
+
+#define HB_VERSION_STRING "0.9.20"
+
+#define HB_VERSION_CHECK(major,minor,micro) \
+ ((major)*10000+(minor)*100+(micro) >= \
+ HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
+
+
+void
+hb_version (unsigned int *major,
+ unsigned int *minor,
+ unsigned int *micro);
+
+const char *
+hb_version_string (void);
+
+hb_bool_t
+hb_version_check (unsigned int major,
+ unsigned int minor,
+ unsigned int micro);
+
+
+HB_END_DECLS
+
+#endif /* HB_VERSION_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-warning.cc b/src/3rdparty/harfbuzz-ng/src/hb-warning.cc
new file mode 100644
index 0000000000..4f1f65f5a2
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-warning.cc
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-atomic-private.hh"
+#include "hb-mutex-private.hh"
+
+
+#if defined(HB_ATOMIC_INT_NIL)
+#ifdef _MSC_VER
+#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe")
+#else
+#warning "Could not find any system to define atomic_int macros, library may NOT be thread-safe"
+#endif
+#endif
+
+#if defined(HB_MUTEX_IMPL_NIL)
+#ifdef _MSC_VER
+#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe")
+#else
+#warning "Could not find any system to define mutex macros, library may NOT be thread-safe"
+#endif
+#endif
+
+#if defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL)
+#ifdef _MSC_VER
+#pragma message("To suppress these warnings, define HB_NO_MT")
+#else
+#warning "To suppress these warnings, define HB_NO_MT"
+#endif
+#endif
+
+
+#include "hb-unicode-private.hh"
+
+#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
+#ifdef _MSC_VER
+#pragma message("Could not find any Unicode functions implementation, you have to provide your own")
+#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS")
+#else
+#warning "Could not find any Unicode functions implementation, you have to provide your own"
+#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS"
+#endif
+#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb.h b/src/3rdparty/harfbuzz-ng/src/hb.h
new file mode 100644
index 0000000000..c5a938a381
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H
+#define HB_H
+#define HB_H_IN
+
+#include "hb-blob.h"
+#include "hb-buffer.h"
+#include "hb-common.h"
+#include "hb-deprecated.h"
+#include "hb-face.h"
+#include "hb-font.h"
+#include "hb-set.h"
+#include "hb-shape.h"
+#include "hb-shape-plan.h"
+#include "hb-unicode.h"
+#include "hb-version.h"
+
+HB_BEGIN_DECLS
+HB_END_DECLS
+
+#undef HB_H_IN
+#endif /* HB_H */
diff --git a/src/3rdparty/harfbuzz.pri b/src/3rdparty/harfbuzz.pri
new file mode 100644
index 0000000000..bc8d49c625
--- /dev/null
+++ b/src/3rdparty/harfbuzz.pri
@@ -0,0 +1,106 @@
+contains(QT_CONFIG, harfbuzz) {
+ QT_HARFBUZZ_DIR = $$QT_SOURCE_TREE/src/3rdparty/harfbuzz-ng
+
+ INCLUDEPATH += $$QT_HARFBUZZ_DIR/include
+
+ SOURCES += \
+ $$QT_HARFBUZZ_DIR/src/hb-blob.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-buffer.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-buffer-serialize.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-common.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-face.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-fallback-shape.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-font.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-tag.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-set.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-shape.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-shape-plan.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-shaper.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-unicode.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-warning.cc
+
+ HEADERS += \
+ $$QT_HARFBUZZ_DIR/src/hb-atomic-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-buffer-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-buffer-deserialize-json.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-buffer-deserialize-text.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-cache-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-face-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-font-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-mutex-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-object-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-open-file-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-open-type-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-head-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-hhea-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-hmtx-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-maxp-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-name-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-set-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-shape-plan-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-shaper-impl-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-shaper-list.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-shaper-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-unicode-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-utf-private.hh
+
+ HEADERS += \
+ $$QT_HARFBUZZ_DIR/src/hb.h \
+ $$QT_HARFBUZZ_DIR/src/hb-blob.h \
+ $$QT_HARFBUZZ_DIR/src/hb-buffer.h \
+ $$QT_HARFBUZZ_DIR/src/hb-common.h \
+ $$QT_HARFBUZZ_DIR/src/hb-face.h \
+ $$QT_HARFBUZZ_DIR/src/hb-font.h \
+ $$QT_HARFBUZZ_DIR/src/hb-set.h \
+ $$QT_HARFBUZZ_DIR/src/hb-shape.h \
+ $$QT_HARFBUZZ_DIR/src/hb-shape-plan.h \
+ $$QT_HARFBUZZ_DIR/src/hb-unicode.h \
+ $$QT_HARFBUZZ_DIR/src/hb-version.h
+
+ # Open Type
+ SOURCES += \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-map.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-default.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-table.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-myanmar.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-sea.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-thai.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-fallback.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-normalize.cc
+
+ HEADERS += \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-common-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gdef-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gpos-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsubgpos-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsub-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-map-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic-fallback.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-machine.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-myanmar-machine.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-sea-machine.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-fallback-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-normalize-private.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-private.hh
+
+ HEADERS += \
+ $$QT_HARFBUZZ_DIR/src/hb-ot.h \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout.h \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-tag.h
+
+ DEFINES += HAVE_CONFIG_H
+ QT += core-private
+
+ TR_EXCLUDE += $$QT_HARFBUZZ_DIR/*
+} else:contains(QT_CONFIG, system-harfbuzz) {
+ LIBS_PRIVATE += -lharfbuzz
+}
diff --git a/src/android/accessibility/accessibility.pro b/src/android/accessibility/accessibility.pro
new file mode 100644
index 0000000000..df5846945d
--- /dev/null
+++ b/src/android/accessibility/accessibility.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = jar
diff --git a/src/android/accessibility/jar/AndroidManifest.xml b/src/android/accessibility/jar/AndroidManifest.xml
new file mode 100644
index 0000000000..dc8343a55a
--- /dev/null
+++ b/src/android/accessibility/jar/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:versionCode="1"
+ android:versionName="1.0"
+ package="org.qtproject.qt5.android.accessibility">
+ <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
+</manifest>
diff --git a/src/android/accessibility/jar/bundledjar.pro b/src/android/accessibility/jar/bundledjar.pro
new file mode 100644
index 0000000000..85ba810310
--- /dev/null
+++ b/src/android/accessibility/jar/bundledjar.pro
@@ -0,0 +1,3 @@
+TARGET = QtAndroidAccessibility-bundled
+CONFIG += bundled_jar_file
+include(jar.pri)
diff --git a/src/android/accessibility/jar/distributedjar.pro b/src/android/accessibility/jar/distributedjar.pro
new file mode 100644
index 0000000000..d161cf0cf6
--- /dev/null
+++ b/src/android/accessibility/jar/distributedjar.pro
@@ -0,0 +1,2 @@
+TARGET = QtAndroidAccessibility
+include(jar.pri)
diff --git a/src/android/accessibility/jar/jar.pri b/src/android/accessibility/jar/jar.pri
new file mode 100644
index 0000000000..23b3ff7087
--- /dev/null
+++ b/src/android/accessibility/jar/jar.pri
@@ -0,0 +1,14 @@
+CONFIG += java
+DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
+API_VERSION = android-16
+
+PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/accessibility
+
+JAVACLASSPATH += $$PWD/src/
+JAVASOURCES += \
+ $$PATHPREFIX/QtAccessibilityDelegate.java \
+ $$PATHPREFIX/QtNativeAccessibility.java
+
+# install
+target.path = $$[QT_INSTALL_PREFIX]/jar
+INSTALLS += target \ No newline at end of file
diff --git a/src/android/accessibility/jar/jar.pro b/src/android/accessibility/jar/jar.pro
new file mode 100644
index 0000000000..8d19c1b7d6
--- /dev/null
+++ b/src/android/accessibility/jar/jar.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += bundledjar.pro distributedjar.pro
diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
new file mode 100644
index 0000000000..669fbaab0d
--- /dev/null
+++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
@@ -0,0 +1,343 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+package org.qtproject.qt5.android.accessibility;
+
+import android.accessibilityservice.AccessibilityService;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.text.TextUtils;
+
+import android.view.accessibility.*;
+import android.view.MotionEvent;
+
+import android.content.Context;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class QtAccessibilityDelegate extends View.AccessibilityDelegate
+{
+ private static final String TAG = "Qt A11Y";
+
+ // Qt uses the upper half of the unsiged integers
+ // all low positive ints should be fine.
+ public static final int INVALID_ID = 333; // half evil
+
+ // The platform might ask for the class implementing the "view".
+ // Pretend to be an inner class of the QtSurface.
+ private static final String DEFAULT_CLASS_NAME = "$VirtualChild";
+
+ private final View m_view;
+ private final AccessibilityManager m_manager;
+
+ // The accessible object that currently has the "accessibility focus"
+ // usually indicated by a yellow rectangle on screen.
+ private int m_focusedVirtualViewId = INVALID_ID;
+ // When exploring the screen by touch, the item "hovered" by the finger.
+ private int m_hoveredVirtualViewId = INVALID_ID;
+
+ // Cache coordinates of the view to know the global offset
+ // this is because the Android platform window does not take
+ // the offset of the view on screen into account (eg status bar on top)
+ private final int[] m_globalOffset = new int[2];
+
+ public QtAccessibilityDelegate(View host)
+ {
+ m_view = host;
+ m_manager = (AccessibilityManager) host.getContext()
+ .getSystemService(Context.ACCESSIBILITY_SERVICE);
+
+ // Enable Qt Accessibility so that notifications are enabled
+ QtNativeAccessibility.setActive(true);
+ }
+
+ @Override
+ public AccessibilityNodeProvider getAccessibilityNodeProvider(View host)
+ {
+ return m_nodeProvider;
+ }
+
+ // For "explore by touch" we need all movement events here first
+ // (user moves finger over screen to discover items on screen).
+ public boolean dispatchHoverEvent(MotionEvent event)
+ {
+ if (!m_manager.isTouchExplorationEnabled()) {
+ return false;
+ }
+
+ int virtualViewId = QtNativeAccessibility.hitTest(event.getX(), event.getY());
+ if (virtualViewId == INVALID_ID) {
+ virtualViewId = View.NO_ID;
+ }
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_HOVER_ENTER:
+ case MotionEvent.ACTION_HOVER_MOVE:
+ setHoveredVirtualViewId(virtualViewId);
+ break;
+ case MotionEvent.ACTION_HOVER_EXIT:
+ setHoveredVirtualViewId(virtualViewId);
+ break;
+ }
+
+ return true;
+ }
+
+ public boolean sendEventForVirtualViewId(int virtualViewId, int eventType)
+ {
+ if ((virtualViewId == INVALID_ID) || !m_manager.isEnabled()) {
+ Log.w(TAG, "sendEventForVirtualViewId for invalid view");
+ return false;
+ }
+
+ final ViewGroup group = (ViewGroup) m_view.getParent();
+ if (group == null) {
+ Log.w(TAG, "Could not send AccessibilityEvent because group was null. This should really not happen.");
+ return false;
+ }
+
+ final AccessibilityEvent event;
+ event = getEventForVirtualViewId(virtualViewId, eventType);
+ return group.requestSendAccessibilityEvent(m_view, event);
+ }
+
+ public void invalidateVirtualViewId(int virtualViewId)
+ {
+ sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+ }
+
+ private void setHoveredVirtualViewId(int virtualViewId)
+ {
+ if (m_hoveredVirtualViewId == virtualViewId) {
+ return;
+ }
+
+ final int previousVirtualViewId = m_hoveredVirtualViewId;
+ m_hoveredVirtualViewId = virtualViewId;
+ sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+ sendEventForVirtualViewId(previousVirtualViewId, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+ }
+
+ private AccessibilityEvent getEventForVirtualViewId(int virtualViewId, int eventType)
+ {
+ final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
+
+ event.setEnabled(true);
+ event.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME);
+
+ event.setContentDescription(QtNativeAccessibility.descriptionForAccessibleObject(virtualViewId));
+ if (event.getText().isEmpty() && TextUtils.isEmpty(event.getContentDescription()))
+ Log.w(TAG, "AccessibilityEvent with empty description");
+
+ event.setPackageName(m_view.getContext().getPackageName());
+ event.setSource(m_view, virtualViewId);
+ return event;
+ }
+
+ private void dumpNodes(int parentId)
+ {
+ Log.i(TAG, "A11Y hierarchy: " + parentId + " parent: " + QtNativeAccessibility.parentId(parentId));
+ Log.i(TAG, " desc: " + QtNativeAccessibility.descriptionForAccessibleObject(parentId) + " rect: " + QtNativeAccessibility.screenRect(parentId));
+ Log.i(TAG, " NODE: " + getNodeForVirtualViewId(parentId));
+ int[] ids = QtNativeAccessibility.childIdListForAccessibleObject(parentId);
+ for (int i = 0; i < ids.length; ++i) {
+ Log.i(TAG, parentId + " has child: " + ids[i]);
+ dumpNodes(ids[i]);
+ }
+ }
+
+ private AccessibilityNodeInfo getNodeForView()
+ {
+ // Since we don't want the parent to be focusable, but we can't remove
+ // actions from a node, copy over the necessary fields.
+ final AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(m_view);
+ final AccessibilityNodeInfo source = AccessibilityNodeInfo.obtain(m_view);
+ m_view.onInitializeAccessibilityNodeInfo(source);
+
+ // Get the actual position on screen, taking the status bar into account.
+ m_view.getLocationOnScreen(m_globalOffset);
+ final int offsetX = m_globalOffset[0];
+ final int offsetY = m_globalOffset[1];
+
+ // Copy over parent and screen bounds.
+ final Rect m_tempParentRect = new Rect();
+ source.getBoundsInParent(m_tempParentRect);
+ result.setBoundsInParent(m_tempParentRect);
+
+ final Rect m_tempScreenRect = new Rect();
+ source.getBoundsInScreen(m_tempScreenRect);
+ m_tempScreenRect.offset(offsetX, offsetY);
+ result.setBoundsInScreen(m_tempScreenRect);
+
+ // Set up the parent view, if applicable.
+ final ViewParent parent = m_view.getParent();
+ if (parent instanceof View) {
+ result.setParent((View) parent);
+ }
+
+ result.setVisibleToUser(source.isVisibleToUser());
+ result.setPackageName(source.getPackageName());
+ result.setClassName(source.getClassName());
+
+// Spit out the entire hierarchy for debugging purposes
+// dumpNodes(-1);
+
+ int[] ids = QtNativeAccessibility.childIdListForAccessibleObject(-1);
+ for (int i = 0; i < ids.length; ++i)
+ result.addChild(m_view, ids[i]);
+
+ return result;
+ }
+
+ private AccessibilityNodeInfo getNodeForVirtualViewId(int virtualViewId)
+ {
+ final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain();
+
+ node.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME);
+ node.setPackageName(m_view.getContext().getPackageName());
+
+ node.setSource(m_view, virtualViewId);
+ QtNativeAccessibility.populateNode(virtualViewId, node);
+ if (TextUtils.isEmpty(node.getText()) && TextUtils.isEmpty(node.getContentDescription()))
+ Log.w(TAG, "AccessibilityNodeInfo with empty contentDescription: " + virtualViewId);
+
+ int parentId = QtNativeAccessibility.parentId(virtualViewId);
+ node.setParent(m_view, parentId);
+
+ Rect screenRect = QtNativeAccessibility.screenRect(virtualViewId);
+ final int offsetX = m_globalOffset[0];
+ final int offsetY = m_globalOffset[1];
+ screenRect.offset(offsetX, offsetY);
+ node.setBoundsInScreen(screenRect);
+
+ Rect rectInParent = screenRect;
+ Rect parentScreenRect = QtNativeAccessibility.screenRect(parentId);
+ rectInParent.offset(-parentScreenRect.left, -parentScreenRect.top);
+ node.setBoundsInParent(rectInParent);
+
+ // Manage internal accessibility focus state.
+ if (m_focusedVirtualViewId == virtualViewId) {
+ node.setAccessibilityFocused(true);
+ node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+ } else {
+ node.setAccessibilityFocused(false);
+ node.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
+ }
+
+ int[] ids = QtNativeAccessibility.childIdListForAccessibleObject(virtualViewId);
+ for (int i = 0; i < ids.length; ++i)
+ node.addChild(m_view, ids[i]);
+ return node;
+ }
+
+ private AccessibilityNodeProvider m_nodeProvider = new AccessibilityNodeProvider()
+ {
+ @Override
+ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId)
+ {
+ if (virtualViewId == View.NO_ID) {
+ return getNodeForView();
+ }
+ return getNodeForVirtualViewId(virtualViewId);
+ }
+
+ @Override
+ public boolean performAction(int virtualViewId, int action, Bundle arguments)
+ {
+ boolean handled = false;
+ //Log.i(TAG, "PERFORM ACTION: " + action + " on " + virtualViewId);
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
+ // Only handle the FOCUS action if it's placing focus on
+ // a different view that was previously focused.
+ if (m_focusedVirtualViewId != virtualViewId) {
+ m_focusedVirtualViewId = virtualViewId;
+ m_view.invalidate();
+ sendEventForVirtualViewId(virtualViewId,
+ AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
+ handled = true;
+ }
+ break;
+ case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
+ if (m_focusedVirtualViewId == virtualViewId) {
+ m_focusedVirtualViewId = INVALID_ID;
+ }
+ // Since we're managing focus at the parent level, we are
+ // likely to receive a FOCUS action before a CLEAR_FOCUS
+ // action. We'll give the benefit of the doubt to the
+ // framework and always handle FOCUS_CLEARED.
+ m_view.invalidate();
+ sendEventForVirtualViewId(virtualViewId,
+ AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+ handled = true;
+ break;
+ default:
+ // Let the node provider handle focus for the view node.
+ if (virtualViewId == View.NO_ID) {
+ return m_view.performAccessibilityAction(action, arguments);
+ }
+ }
+ handled |= performActionForVirtualViewId(virtualViewId, action, arguments);
+
+ return handled;
+ }
+ };
+
+ protected boolean performActionForVirtualViewId(int virtualViewId, int action, Bundle arguments)
+ {
+// Log.i(TAG, "ACTION " + action + " on " + virtualViewId);
+// dumpNodes(virtualViewId);
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_CLICK:
+ boolean success = QtNativeAccessibility.clickAction(virtualViewId);
+ if (success)
+ sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
+ return success;
+ }
+ return false;
+ }
+}
diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
new file mode 100644
index 0000000000..b1cc82c065
--- /dev/null
+++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android.accessibility;
+
+import android.graphics.Rect;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+class QtNativeAccessibility
+{
+ static native void setActive(boolean enable);
+ static native int[] childIdListForAccessibleObject(int objectId);
+ static native int parentId(int objectId);
+ static native String descriptionForAccessibleObject(int objectId);
+ static native Rect screenRect(int objectId);
+ static native int hitTest(float x, float y);
+ static native boolean clickAction(int objectId);
+
+ static native void populateNode(int objectId, AccessibilityNodeInfo node);
+}
diff --git a/src/android/android.pro b/src/android/android.pro
index a5db78e32f..1850f012c0 100644
--- a/src/android/android.pro
+++ b/src/android/android.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS = jar java
+SUBDIRS = jar java accessibility
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 06ece9d04c..8dc804cce4 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -160,6 +160,12 @@ public class QtActivityDelegate
private final int ImhEmailCharactersOnly = 0x200000;
private final int ImhUrlCharactersOnly = 0x400000;
+ // application state
+ private final int ApplicationSuspended = 0x0;
+ private final int ApplicationHidden = 0x1;
+ private final int ApplicationInactive = 0x2;
+ private final int ApplicationActive = 0x4;
+
public void resetSoftwareKeyboard()
{
if (m_imm == null)
@@ -310,7 +316,7 @@ public class QtActivityDelegate
try {
@SuppressWarnings("rawtypes")
- Class initClass = classLoader.loadClass(className);
+ Class<?> initClass = classLoader.loadClass(className);
Object staticInitDataObject = initClass.newInstance(); // create an instance
Method m = initClass.getMethod("setActivity", Activity.class, Object.class);
m.invoke(staticInitDataObject, m_activity, this);
@@ -621,6 +627,11 @@ public class QtActivityDelegate
m_surface.applicationStarted(true);
}
+ public void onPause()
+ {
+ QtNative.updateApplicationState(ApplicationInactive);
+ }
+
public void onResume()
{
// fire all lostActions
@@ -631,12 +642,18 @@ public class QtActivityDelegate
m_activity.runOnUiThread(itr.next());
if (m_started) {
+ QtNative.updateApplicationState(ApplicationActive);
QtNative.clearLostActions();
QtNative.updateWindow();
}
}
}
+ public void onStop()
+ {
+ QtNative.updateApplicationState(ApplicationSuspended);
+ }
+
public Object onRetainNonConfigurationInstance()
{
try {
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 122fc55aad..51f00a73c6 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -582,6 +582,9 @@ public class QtNative
public static native void updateWindow();
// window methods
+ // application methods
+ public static native void updateApplicationState(int state);
+
// menu methods
public static native boolean onPrepareOptionsMenu(Menu menu);
public static native boolean onOptionsItemSelected(int itemId, boolean checked);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
index 6cc2f1e333..cd0bddf2c8 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
@@ -55,17 +55,23 @@ import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
{
private Bitmap m_bitmap = null;
private boolean m_started = false;
private boolean m_usesGL = false;
private GestureDetector m_gestureDetector;
+ private Object m_accessibilityDelegate = null;
public QtSurface(Context context, int id)
{
super(context);
- setFocusable(true);
+ setFocusable(false);
+ setFocusableInTouchMode(false);
+
getHolder().addCallback(this);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
setId(id);
@@ -107,6 +113,44 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
if (m_usesGL)
holder.setFormat(PixelFormat.RGBA_8888);
+
+
+ // Initialize Accessibility
+ // The accessibility code depends on android API level 16, so dynamically resolve it
+ try {
+ final String a11yDelegateClassName = "org.qtproject.qt5.android.accessibility.QtAccessibilityDelegate";
+ Class<?> qtDelegateClass = Class.forName(a11yDelegateClassName);
+ Constructor constructor = qtDelegateClass.getConstructor(Class.forName("android.view.View"));
+ m_accessibilityDelegate = constructor.newInstance(this);
+
+ Class a11yDelegateClass = Class.forName("android.view.View$AccessibilityDelegate");
+ Method setDelegateMethod = this.getClass().getMethod("setAccessibilityDelegate", a11yDelegateClass);
+ setDelegateMethod.invoke(this, m_accessibilityDelegate);
+ } catch (ClassNotFoundException e) {
+ // Class not found is fine since we are compatible with Android API < 16, but the function will
+ // only be available with that API level.
+ } catch (Exception e) {
+ // Unknown exception means something went wrong.
+ Log.w("Qt A11y", "Unknown exception: " + e.toString());
+ }
+ }
+
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ // Always attempt to dispatch hover events to accessibility first.
+ if (m_accessibilityDelegate != null) {
+ try {
+ Method dispHoverA11y = m_accessibilityDelegate.getClass().getMethod("dispatchHoverEvent", MotionEvent.class);
+ boolean ret = (Boolean) dispHoverA11y.invoke(m_accessibilityDelegate, event);
+ if (ret)
+ return true;
+ SurfaceView view = (SurfaceView) this;
+ Method dispHoverView = view.getClass().getMethod("dispatchHoverEvent", MotionEvent.class);
+ return (Boolean) dispHoverView.invoke(view, event);
+ } catch (Exception e) {
+ Log.w("Qt A11y", "EXCEPTION in dispatchHoverEvent for Accessibility: " + e);
+ }
+ }
+ return false;
}
@Override
diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml
index 2a6f52b315..c0aa5c9abf 100644
--- a/src/android/java/AndroidManifest.xml
+++ b/src/android/java/AndroidManifest.xml
@@ -31,6 +31,7 @@
<!-- Splash screen -->
</activity>
</application>
+ <uses-sdk android:targetSdkVersion="14" android:minSdkVersion="9"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf
index 3d5e9de5e0..7fa437c17f 100644
--- a/src/concurrent/doc/qtconcurrent.qdocconf
+++ b/src/concurrent/doc/qtconcurrent.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/qtconcurrent \
excludedirs += ../../../examples/widgets/doc
imagedirs += images
+
+navigation.landingpage = "Qt Concurrent"
+navigation.cppclassespage = "Qt Concurrent C++ Classes"
diff --git a/src/concurrent/doc/src/qtconcurrent-module.qdoc b/src/concurrent/doc/src/qtconcurrent-module.qdoc
index b8d89cbde3..37298017c7 100644
--- a/src/concurrent/doc/src/qtconcurrent-module.qdoc
+++ b/src/concurrent/doc/src/qtconcurrent-module.qdoc
@@ -31,6 +31,7 @@
\brief The Qt Concurrent module contains functionality to support concurrent execution of program code
\ingroup modules
+ \qtvariable concurrent
The Qt Concurrent module extends the basic threading support found in \l{Qt Core} module and
simplifies the development of code that can be executed in parallel on all available CPU cores.
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index db482fa9e6..2d87783107 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -55,11 +55,8 @@ set_property(TARGET Qt5::Core APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION
)
-!!IF isEmpty(CMAKE_HOST_DATA_DIR_IS_ABSOLUTE)
-set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_HOST_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
-!!ELSE
-set(_qt5_corelib_extra_includes \"$${CMAKE_HOST_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
-!!ENDIF
+include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5CoreConfigExtrasMkspecDir.cmake\")
+
foreach(_dir ${_qt5_corelib_extra_includes})
_qt5_Core_check_file_exists(${_dir})
endforeach()
diff --git a/src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in b/src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in
new file mode 100644
index 0000000000..c357237d0e
--- /dev/null
+++ b/src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in
@@ -0,0 +1,6 @@
+
+!!IF isEmpty(CMAKE_HOST_DATA_DIR_IS_ABSOLUTE)
+set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_HOST_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
+!!ELSE
+set(_qt5_corelib_extra_includes \"$${CMAKE_HOST_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
+!!ENDIF
diff --git a/src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in b/src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in
new file mode 100644
index 0000000000..706304cf34
--- /dev/null
+++ b/src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in
@@ -0,0 +1,6 @@
+
+!!IF isEmpty(CMAKE_INSTALL_DATA_DIR_IS_ABSOLUTE)
+set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_INSTALL_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
+!!ELSE
+set(_qt5_corelib_extra_includes \"$${CMAKE_INSTALL_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
+!!ENDIF
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 44a3f06f50..65bffd87bd 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -17,12 +17,14 @@ win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
QMAKE_DOCS = $$PWD/doc/qtcore.qdocconf
ANDROID_JAR_DEPENDENCIES = \
- jar/QtAndroid.jar
+ jar/QtAndroid.jar \
+ jar/QtAndroidAccessibility.jar
ANDROID_LIB_DEPENDENCIES = \
plugins/platforms/android/libqtforandroid.so \
libs/libgnustl_shared.so
ANDROID_BUNDLED_JAR_DEPENDENCIES = \
- jar/QtAndroid-bundled.jar
+ jar/QtAndroid-bundled.jar \
+ jar/QtAndroidAccessibility-bundled.jar
load(qt_module)
@@ -77,12 +79,32 @@ cmake_umbrella_config_file.output = $$DESTDIR/cmake/Qt5/Qt5Config.cmake
cmake_umbrella_config_version_file.input = $$PWD/../../mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in
cmake_umbrella_config_version_file.output = $$DESTDIR/cmake/Qt5/Qt5ConfigVersion.cmake
+load(cmake_functions)
+
+CMAKE_HOST_DATA_DIR = $$cmakeRelativePath($$[QT_HOST_DATA/src], $$[QT_INSTALL_PREFIX])
+contains(CMAKE_HOST_DATA_DIR, "^\\.\\./.*"):!isEmpty(CMAKE_HOST_DATA_DIR) {
+ CMAKE_HOST_DATA_DIR = $$[QT_HOST_DATA/src]/
+ CMAKE_HOST_DATA_DIR_IS_ABSOLUTE = True
+}
+
+cmake_extras_mkspec_dir.input = $$PWD/Qt5CoreConfigExtrasMkspecDir.cmake.in
+cmake_extras_mkspec_dir.output = $$DESTDIR/cmake/Qt5Core/Qt5CoreConfigExtrasMkspecDir.cmake
+
+CMAKE_INSTALL_DATA_DIR = $$cmakeRelativePath($$[QT_HOST_DATA], $$[QT_INSTALL_PREFIX])
+contains(CMAKE_INSTALL_DATA_DIR, "^\\.\\./.*"):!isEmpty(CMAKE_INSTALL_DATA_DIR) {
+ CMAKE_INSTALL_DATA_DIR = $$[QT_HOST_DATA]/
+ CMAKE_INSTALL_DATA_DIR_IS_ABSOLUTE = True
+}
+
+cmake_extras_mkspec_dir_for_install.input = $$PWD/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in
+cmake_extras_mkspec_dir_for_install.output = $$DESTDIR/cmake/install/Qt5Core/Qt5CoreConfigExtrasMkspecDir.cmake
+
cmake_qt5_umbrella_module_files.files = $$cmake_umbrella_config_file.output $$cmake_umbrella_config_version_file.output
cmake_qt5_umbrella_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5
-QMAKE_SUBSTITUTES += ctest_macros_file cmake_umbrella_config_file cmake_umbrella_config_version_file
+QMAKE_SUBSTITUTES += ctest_macros_file cmake_umbrella_config_file cmake_umbrella_config_version_file cmake_extras_mkspec_dir cmake_extras_mkspec_dir_for_install
-ctest_qt5_module_files.files += $$ctest_macros_file.output
+ctest_qt5_module_files.files += $$ctest_macros_file.output $$cmake_extras_mkspec_dir_for_install.output
ctest_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5Core
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 752e8eb946..fdd46995c5 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -40,3 +40,8 @@ exampledirs += \
../../../examples/json/
imagedirs += images
+
+excludedirs += snippets
+
+navigation.landingpage = "Qt Core"
+navigation.cppclassespage = "Qt Core C++ Classes"
diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp
index 532a0e1f59..91eaf298e1 100644
--- a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp
@@ -85,3 +85,9 @@ QByteArray ba = QUrl::toPercentEncoding("{a fishy string?}", "{}", "s");
qDebug(ba.constData());
// prints "{a fi%73hy %73tring%3F}"
//! [6]
+
+//! [7]
+QUrl url("http://qt-project.org/support/file.html");
+// url.adjusted(RemoveFilename) == "http://qt-project.org/support/"
+// url.fileName() == "file.html"
+//! [7]
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
index 25d24185ee..ab909e5065 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
@@ -134,3 +134,61 @@ return QVariant::fromValue(s);
QObject *object = getObjectFromSomewhere();
QVariant data = QVariant::fromValue(object);
//! [8]
+
+//! [9]
+
+QList<int> intList;
+intList.push_back(7);
+intList.push_back(11);
+intList.push_back(42);
+
+QVariant variant = QVariant::fromValue(intList);
+if (variant.canConvert<QVariantList>()) {
+ QSequentialIterable iterable = variant.value<QSequentialIterable>();
+ // Can use foreach:
+ foreach (const QVariant &v, iterable) {
+ qDebug() << v;
+ }
+ // Can use C++11 range-for:
+ for (const QVariant &v : iterable) {
+ qDebug() << v;
+ }
+ // Can use iterators:
+ QSequentialIterable::const_iterator it = iterable.begin();
+ const QSequentialIterable::const_iterator end = iterable.end();
+ for ( ; it != end; ++it) {
+ qDebug() << *it;
+ }
+}
+
+//! [9]
+
+//! [10]
+
+QHash<int, QString> mapping;
+mapping.insert(7, "Seven");
+mapping.insert(11, "Eleven");
+mapping.insert(42, "Forty-two");
+
+QVariant variant = QVariant::fromValue(mapping);
+if (variant.canConvert<QVariantHash>()) {
+ QAssociativeIterable iterable = variant.value<QAssociativeIterable>();
+ // Can use foreach over the values:
+ foreach (const QVariant &v, iterable) {
+ qDebug() << v;
+ }
+ // Can use C++11 range-for over the values:
+ for (const QVariant &v : iterable) {
+ qDebug() << v;
+ }
+ // Can use iterators:
+ QAssociativeIterable::const_iterator it = iterable.begin();
+ const QAssociativeIterable::const_iterator end = iterable.end();
+ for ( ; it != end; ++it) {
+ qDebug() << *it; // The current value
+ qDebug() << it.key();
+ qDebug() << it.value();
+ }
+}
+
+//! [10]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineoption.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineoption.cpp
new file mode 100644
index 0000000000..d4c745215f
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineoption.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 David Faure <faure@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+QCommandLineOption verboseOption("verbose", "Verbose mode. Prints out more information.");
+QCommandLineOption outputOption(QStringList() << "o" << "output", "Write generated data into <file>.", "file");
+//! [0]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineparser.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineparser.cpp
new file mode 100644
index 0000000000..569cb6af80
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qcommandlineparser.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 David Faure <faure@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+bool verbose = parser.isSet("verbose");
+//! [0]
+
+//! [1]
+// Usage: image-editor file
+//
+// Arguments:
+// file The file to open.
+parser.addPositionalArgument("file", QCoreApplication::translate("main", "The file to open."));
+
+// Usage: web-browser [urls...]
+//
+// Arguments:
+// urls URLs to open, optionally.
+parser.addPositionalArgument("urls", QCoreApplication::translate("main", "URLs to open, optionally."), "[urls...]");
+
+// Usage: cp source destination
+//
+// Arguments:
+// source Source file to copy.
+// destination Destination directory.
+parser.addPositionalArgument("source", QCoreApplication::translate("main", "Source file to copy."));
+parser.addPositionalArgument("destination", QCoreApplication::translate("main", "Destination directory."));
+//! [1]
+
+//! [2]
+parser.addPositionalArgument("command", "The command to execute.");
+
+// Call parse() to find out the positional arguments.
+parser.parse(QCoreApplication::arguments());
+
+const QStringList args = parser.positionalArguments();
+const QString command = args.isEmpty() ? QString() : args.first();
+if (command == "resize") {
+ parser.clearPositionalArguments();
+ parser.addPositionalArgument("resize", "Resize the object to a new size.", "resize [resize_options]");
+ parser.addOption(QCommandLineOption("size", "New size.", "new_size"));
+ parser.process(app);
+ // ...
+}
+
+This code results in context-dependent help:
+
+$ tool --help
+Usage: tool command
+
+Arguments:
+ command The command to execute.
+
+$ tool resize --help
+Usage: tool resize [resize_options]
+
+Options:
+ --size <size> New size.
+
+Arguments:
+ resize Resize the object to a new size.
+
+//! [2]
+
+//! [3]
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+ app.setApplicationName("my-copy-program");
+ app.setApplicationVersion("1.0");
+
+ QCommandLineParser parser;
+ parser.addHelpOption("Test helper");
+ parser.addVersionOption();
+ parser.addRemainingArgument("source", QCoreApplication::translate("main", "Source file to copy."));
+ parser.addRemainingArgument("destination", QCoreApplication::translate("main", "Destination directory."));
+
+ // A boolean option with a single name (-p)
+ QCommandLineOption showProgressOption("p", QCoreApplication::translate("main", "Show progress during copy"));
+ parser.addOption(showProgressOption);
+
+ // A boolean option with multiple names (-f, --force)
+ QCommandLineOption forceOption(QStringList() << "f" << "force", "Overwrite existing files.");
+ parser.addOption(forceOption);
+
+ // An option with a value
+ QCommandLineOption targetDirectoryOption(QStringList() << "t" << "target-directory",
+ QCoreApplication::translate("main", "Copy all source files into <directory>."),
+ QCoreApplication::translate("main", "directory"));
+ parser.addOption(targetDirectoryOption);
+
+ // Process the actual command line arguments given by the user
+ parser.process(app);
+
+ const QStringList args = parser.remainingArguments();
+ // source is args.at(0), destination is args.at(1)
+
+ bool showProgress = parser.isSet(showProgressOption);
+ bool force = parser.isSet(forceOption);
+ QString targetDir = parser.value(targetDirectoryOption);
+ // ...
+}
+
+//! [3]
diff --git a/src/corelib/doc/src/qtcore-index.qdoc b/src/corelib/doc/src/qtcore-index.qdoc
index 9568ea9f8e..fef5f6092b 100644
--- a/src/corelib/doc/src/qtcore-index.qdoc
+++ b/src/corelib/doc/src/qtcore-index.qdoc
@@ -37,6 +37,8 @@
\snippet code/doc_src_qtcore.cpp 0
+ If you use \l qmake to build your projects, Qt Core is included by default.
+
\section1 Core Functionalities
Qt adds these features to C++:
diff --git a/src/corelib/doc/src/qtcore.qdoc b/src/corelib/doc/src/qtcore.qdoc
index 155a6cd8c0..0ded568297 100644
--- a/src/corelib/doc/src/qtcore.qdoc
+++ b/src/corelib/doc/src/qtcore.qdoc
@@ -29,6 +29,7 @@
\module QtCore
\title Qt Core C++ Classes
\ingroup modules
+ \qtvariable core
\brief Provides core non-GUI functionality.
@@ -36,4 +37,8 @@
definitions of the module's classes, use the following directive:
\snippet code/doc_src_qtcore.cpp 0
+
+ If you use \l qmake to build your projects, \l{Qt Core} is included by
+ default.
+
*/
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index f899d63a4d..5b6639d56b 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -151,7 +151,7 @@
/* Intel C++ also masquerades as GCC */
# define Q_CC_INTEL
# define Q_ASSUME_IMPL(expr) __assume(expr)
-# define Q_UNREACHABLE_IMPL() __assume(0)
+# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# elif defined(__clang__)
/* Clang also masquerades as GCC */
# define Q_CC_CLANG
@@ -496,6 +496,15 @@
# define Q_COMPILER_INITIALIZER_LISTS
# define Q_COMPILER_NOEXCEPT
# endif
+# if __INTEL_COMPILER >= 1400
+# define Q_COMPILER_CONSTEXPR
+# define Q_COMPILER_DELEGATING_CONSTRUCTORS
+# define Q_COMPILER_EXPLICIT_OVERRIDES
+# define Q_COMPILER_NONSTATIC_MEMBER_INIT
+# define Q_COMPILER_RAW_STRINGS
+# define Q_COMPILER_REF_QUALIFIERS
+# define Q_COMPILER_UNRESTRICTED_UNIONS
+# endif
# endif
#endif
@@ -881,4 +890,26 @@
Q_UNUSED(valueOfExpression); /* the value may not be used if Q_ASSERT_X and Q_ASSUME_IMPL are noop */\
} while (0)
+
+/*
+ Sanitize compiler feature availability
+*/
+#if !defined(Q_PROCESSOR_X86)
+# undef QT_COMPILER_SUPPORTS_SSE2
+# undef QT_COMPILER_SUPPORTS_SSE3
+# undef QT_COMPILER_SUPPORTS_SSSE3
+# undef QT_COMPILER_SUPPORTS_SSE4_1
+# undef QT_COMPILER_SUPPORTS_SSE4_2
+# undef QT_COMPILER_SUPPORTS_AVX
+# undef QT_COMPILER_SUPPORTS_AVX2
+#endif
+#if !defined(Q_PROCESSOR_ARM)
+# undef QT_COMPILER_SUPPORTS_IWMMXT
+# undef QT_COMPILER_SUPPORTS_NEON
+#endif
+#if !defined(Q_PROCESSOR_MIPS)
+# undef QT_COMPILER_SUPPORTS_MIPS_DSP
+# undef QT_COMPILER_SUPPORTS_MIPS_DSPR2
+#endif
+
#endif // QCOMPILERDETECTION_H
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 6e5de68b01..9656f4b68a 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -934,7 +934,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\endlist
Some constants are defined only on certain platforms. You can use
- the preprocessor symbols Q_OS_WIN and Q_OS_MACX to test that
+ the preprocessor symbols Q_OS_WIN and Q_OS_OSX to test that
the application is compiled under Windows or OS X.
\sa QLibraryInfo
@@ -1077,18 +1077,20 @@ bool qSharedBuild() Q_DECL_NOTHROW
\macro Q_OS_DARWIN
\relates <QtGlobal>
- Defined on Darwin OS (synonym for Q_OS_MAC).
+ Defined on Darwin-based operating systems such as OS X and iOS,
+ including any open source version(s) of Darwin.
*/
/*!
\macro Q_OS_MAC
\relates <QtGlobal>
- Defined on OS X and iOS (synonym for Q_OS_DARWIN).
+ Defined on Darwin-based operating systems distributed by Apple, which
+ currently includes OS X and iOS, but not the open source version.
*/
/*!
- \macro Q_OS_MACX
+ \macro Q_OS_OSX
\relates <QtGlobal>
Defined on OS X.
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index a70dc52e9f..e72ea792dd 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -45,11 +45,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.1.2"
+#define QT_VERSION_STR "5.2.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050102
+#define QT_VERSION 0x050200
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -68,12 +68,15 @@
#define QT_STRINGIFY(x) QT_STRINGIFY2(x)
#include <QtCore/qsystemdetection.h>
-#include <QtCore/qcompilerdetection.h>
#include <QtCore/qprocessordetection.h>
+#include <QtCore/qcompilerdetection.h>
#if defined (__ELF__)
# define Q_OF_ELF
#endif
+#if defined (__MACH__) && defined (__APPLE__)
+# define Q_OF_MACH_O
+#endif
#ifdef __cplusplus
@@ -674,11 +677,13 @@ typedef void (*QFunctionPointer)();
# define Q_UNIMPLEMENTED() qWarning("%s:%d: %s: Unimplemented code.", __FILE__, __LINE__, Q_FUNC_INFO)
#endif
+Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) Q_REQUIRED_RESULT;
Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2)
{
return (qAbs(p1 - p2) * 1000000000000. <= qMin(qAbs(p1), qAbs(p2)));
}
+Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2) Q_REQUIRED_RESULT;
Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2)
{
return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2)));
@@ -687,6 +692,7 @@ Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2)
/*!
\internal
*/
+Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(double d) Q_REQUIRED_RESULT;
Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(double d)
{
return qAbs(d) <= 0.000000000001;
@@ -695,6 +701,7 @@ Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(double d)
/*!
\internal
*/
+Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f) Q_REQUIRED_RESULT;
Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f)
{
return qAbs(f) <= 0.00001f;
@@ -705,6 +712,7 @@ Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f)
check whether the actual value is 0 or close to 0, but whether
it is binary 0, disregarding sign.
*/
+static inline bool qIsNull(double d) Q_REQUIRED_RESULT;
static inline bool qIsNull(double d)
{
union U {
@@ -721,6 +729,7 @@ static inline bool qIsNull(double d)
check whether the actual value is 0 or close to 0, but whether
it is binary 0, disregarding sign.
*/
+static inline bool qIsNull(float f) Q_REQUIRED_RESULT;
static inline bool qIsNull(float f)
{
union U {
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 2b305ef68b..61841cab76 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -78,6 +78,7 @@ struct QLibrarySettings
QLibrarySettings();
QScopedPointer<QSettings> settings;
#ifdef QT_BOOTSTRAPPED
+ bool haveEffectiveSourcePaths;
bool haveEffectivePaths;
bool havePaths;
#endif
@@ -99,8 +100,10 @@ public:
static bool haveGroup(QLibraryInfo::PathGroup group)
{
QLibrarySettings *ls = qt_library_settings();
- return ls ? (group == QLibraryInfo::EffectivePaths
- ? ls->haveEffectivePaths : ls->havePaths) : false;
+ return ls ? (group == QLibraryInfo::EffectiveSourcePaths
+ ? ls->haveEffectiveSourcePaths
+ : group == QLibraryInfo::EffectivePaths
+ ? ls->haveEffectivePaths : ls->havePaths) : false;
}
#endif
static QSettings *configuration()
@@ -122,7 +125,12 @@ QLibrarySettings::QLibrarySettings()
// This code needs to be in the regular library, as otherwise a qt.conf that
// works for qmake would break things for dynamically built Qt tools.
QStringList children = settings->childGroups();
+#ifdef QT_BOOTSTRAPPED
+ haveEffectiveSourcePaths = children.contains(QLatin1String("EffectiveSourcePaths"));
+ haveEffectivePaths = haveEffectiveSourcePaths || children.contains(QLatin1String("EffectivePaths"));
+#else
haveEffectivePaths = children.contains(QLatin1String("EffectivePaths"));
+#endif
// Backwards compat: an existing but empty file is claimed to contain the Paths section.
havePaths = !haveEffectivePaths || children.contains(QLatin1String("Paths"));
#ifndef QT_BOOTSTRAPPED
@@ -130,6 +138,9 @@ QLibrarySettings::QLibrarySettings()
settings.reset(0);
#else
} else {
+#ifdef QT_BOOTSTRAPPED
+ haveEffectiveSourcePaths = false;
+#endif
haveEffectivePaths = false;
havePaths = false;
#endif
@@ -334,9 +345,12 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
// and qt.conf with that section is present, use it, otherwise fall back to
// FinalPaths. For FinalPaths, use qt.conf if present and contains not only
// [EffectivePaths], otherwise fall back to builtins.
+ // EffectiveSourcePaths falls back to EffectivePaths.
if (!QLibraryInfoPrivate::haveGroup(group)
- && (group == FinalPaths
- || !(group = FinalPaths, QLibraryInfoPrivate::haveGroup(FinalPaths))))
+ && !(group == EffectiveSourcePaths
+ && (group = EffectivePaths, QLibraryInfoPrivate::haveGroup(group)))
+ && !(group == EffectivePaths
+ && (group = FinalPaths, QLibraryInfoPrivate::haveGroup(group))))
#elif !defined(QT_NO_SETTINGS)
if (!QLibraryInfoPrivate::configuration())
#endif
@@ -368,6 +382,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
QSettings *config = QLibraryInfoPrivate::configuration();
config->beginGroup(QLatin1String(
#ifdef QT_BOOTSTRAPPED
+ group == EffectiveSourcePaths ? "EffectiveSourcePaths" :
group == EffectivePaths ? "EffectivePaths" :
#endif
"Paths"));
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index b275e018a0..17864b555b 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -92,7 +92,7 @@ public:
};
static QString location(LibraryLocation); // ### Qt 6: consider renaming it to path()
#ifdef QT_BOOTSTRAPPED
- enum PathGroup { FinalPaths, EffectivePaths };
+ enum PathGroup { FinalPaths, EffectivePaths, EffectiveSourcePaths };
static QString rawLocation(LibraryLocation, PathGroup);
#endif
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 25c47d5d34..81329fd5ba 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -89,12 +89,14 @@ Qt {
Q_ENUMS(ScreenOrientation)
Q_FLAGS(ScreenOrientations)
Q_ENUMS(ConnectionType)
+ Q_ENUMS(ApplicationState)
#ifndef QT_NO_GESTURES
Q_ENUMS(GestureState)
Q_ENUMS(GestureType)
#endif
Q_ENUMS(CursorMoveStyle)
Q_ENUMS(TimerType)
+ Q_ENUMS(ScrollPhase)
#endif // defined(Q_MOC_RUN)
#if defined(Q_MOC_RUN)
@@ -982,6 +984,14 @@ public:
Key_MicMute = 0x01000113,
+ Key_Red = 0x01000114,
+ Key_Green = 0x01000115,
+ Key_Yellow = 0x01000116,
+ Key_Blue = 0x01000117,
+
+ Key_ChannelUp = 0x01000118,
+ Key_ChannelDown = 0x01000119,
+
Key_MediaLast = 0x0100ffff,
// Keypad navigation keys
@@ -1173,7 +1183,8 @@ public:
SystemLocaleShortDate,
SystemLocaleLongDate,
DefaultLocaleShortDate,
- DefaultLocaleLongDate
+ DefaultLocaleLongDate,
+ RFC2822Date // RFC 2822 (+ 850 and 1036 during parsing)
};
enum TimeSpec {
@@ -1560,6 +1571,12 @@ public:
CoarseTimer,
VeryCoarseTimer
};
+
+ enum ScrollPhase {
+ ScrollBegin = 1,
+ ScrollUpdate,
+ ScrollEnd
+ };
}
#ifdef Q_MOC_RUN
;
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 677cddc87e..03ac8c6153 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -585,6 +585,10 @@
\value LocalDate \e{This enum value is deprecated.} Use Qt::SystemLocaleShortDate
instead (or Qt::SystemLocaleLongDate if you want long dates).
+ \value RFC2822Date \l{RFC 2822}, \l{RFC 850} and \l{RFC 1036} format: either
+ \c{[ddd,] dd MMM yyyy hh:mm[:ss] +/-TZ} or \c{ddd MMM dd yyyy hh:mm[:ss] +/-TZ}
+ for combined dates and times.
+
\note For \c ISODate formats, each \c Y, \c M and \c D represents a single digit
of the year, month and day used to specify the date. Each \c H, \c M and \c S
represents a single digit of the hour, minute and second used to specify the time.
@@ -1618,6 +1622,12 @@
\value Key_TouchpadOn
\value Key_TouchpadOff
\value Key_MicMute
+ \value Key_Red
+ \value Key_Green
+ \value Key_Yellow
+ \value Key_Blue
+ \value Key_ChannelUp
+ \value Key_ChannelDown
\value Key_MediaLast
\value Key_unknown
@@ -2864,3 +2874,18 @@
nearest full second (e.g. an interval of 23500ms will be rounded to
24000ms, and 20300ms to 20000ms).
*/
+
+/*!
+ \enum Qt::ScrollPhase
+ \since 5.2
+
+ This enum describes the phase of scrolling.
+
+ \value ScrollBegin Scrolling is about to begin, but the scrolling
+ distance did not yet change.
+
+ \value ScrollUpdate The scrolling distance has changed (default).
+
+ \value ScrollEnd Scrolling has ended, but the scrolling distance
+ did not change anymore.
+*/
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index 21f9c8f44f..ca7689c527 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -157,11 +157,33 @@
X86 is little-endian.
*/
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
-# define Q_PROCESSOR_X86
# define Q_PROCESSOR_X86_32
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+
+/*
+ * We define Q_PROCESSOR_X86 == 6 for anything above a equivalent or better
+ * than a Pentium Pro (the processor whose architecture was called P6) or an
+ * Athlon.
+ *
+ * All processors since the Pentium III and the Athlon 4 have SSE support, so
+ * we use that to detect. That leaves the original Athlon, Pentium Pro and
+ * Pentium II.
+ */
+
+# if defined(_M_IX86)
+# define Q_PROCESSOR_X86 (_M_IX86/100)
+# elif defined(__i686__) || defined(__athlon__) || defined(__SSE__)
+# define Q_PROCESSOR_X86 6
+# elif defined(__i586__) || defined(__k6__)
+# define Q_PROCESSOR_X86 5
+# elif defined(__i486__)
+# define Q_PROCESSOR_X86 4
+# else
+# define Q_PROCESSOR_X86 3
+# endif
+
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
-# define Q_PROCESSOR_X86
+# define Q_PROCESSOR_X86 6
# define Q_PROCESSOR_X86_64
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index b638b4d509..dc9fa7383a 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -49,9 +49,9 @@
/*
The operating system, must be one of: (Q_OS_x)
- DARWIN - Darwin OS (synonym for Q_OS_MAC)
- MAC - OS X or iOS (synonym for Q_OS_DARWIN)
- MACX - OS X
+ DARWIN - Any Darwin system
+ MAC - OS X and iOS
+ OSX - OS X
IOS - iOS
MSDOS - MS-DOS and Windows
OS2 - OS/2
@@ -186,8 +186,9 @@
# include <TargetConditionals.h>
# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
# define Q_OS_IOS
-# else
-# define Q_OS_MACX
+# elif defined(TARGET_OS_MAC) && TARGET_OS_MAC
+# define Q_OS_OSX
+# define Q_OS_MACX // compatibility synonym
# endif
#endif
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index b6926bc544..008460df5d 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -251,7 +251,7 @@ QT_BEGIN_NAMESPACE
return retVal;
enum {
- DefaultStreamVersion = QDataStream::Qt_5_1
+ DefaultStreamVersion = QDataStream::Qt_5_2
};
/*!
@@ -540,6 +540,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_4_9 Same as Qt_4_6.
\value Qt_5_0 Version 13 (Qt 5.0)
\value Qt_5_1 Version 14 (Qt 5.1)
+ \value Qt_5_2 Version 15 (Qt 5.2)
\sa setVersion(), version()
*/
@@ -571,6 +572,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\table
\header \li Qt Version \li QDataStream Version
+ \row \li Qt 5.2 \li 15
\row \li Qt 5.1 \li 14
\row \li Qt 5.0 \li 13
\row \li Qt 4.6 \li 12
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 969cdf4517..f107e801b6 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -86,8 +86,9 @@ public:
Qt_4_8 = Qt_4_7,
Qt_4_9 = Qt_4_8,
Qt_5_0 = 13,
- Qt_5_1 = 14
-#if QT_VERSION >= 0x050200
+ Qt_5_1 = 14,
+ Qt_5_2 = 15
+#if QT_VERSION >= 0x050300
#error Add the datastream version for this Qt version
#endif
};
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 9ca512e84f..c984f28bd0 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -52,7 +52,6 @@
#include "qstring.h"
#include "qregexp.h"
#include "qvector.h"
-#include "qalgorithms.h"
#include "qvarlengtharray.h"
#include "qfilesystementry_p.h"
#include "qfilesystemmetadata_p.h"
@@ -64,6 +63,7 @@
# include "private/qcoreglobaldata_p.h"
#endif
+#include <algorithm>
#include <stdlib.h>
QT_BEGIN_NAMESPACE
@@ -308,7 +308,7 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l,
QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]);
for (int i = 0; i < n; ++i)
si[i].item = l.at(i);
- qSort(si.data(), si.data() + n, QDirSortItemComparator(sort));
+ std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort));
// put them back in the list(s)
if (infos) {
for (int i = 0; i < n; ++i)
@@ -2005,25 +2005,14 @@ bool QDir::match(const QString &filter, const QString &fileName)
#endif // QT_NO_REGEXP
/*!
- Returns \a path with directory separators normalized (converted to "/") and
- redundant ones removed, and "."s and ".."s resolved (as far as possible).
-
- Symbolic links are kept. This function does not return the
- canonical path, but rather the simplest version of the input.
- For example, "./local" becomes "local", "local/../bin" becomes
- "bin" and "/local/usr/../bin" becomes "/local/bin".
+ Returns \a path with redundant directory separators removed,
+ and "."s and ".."s resolved (as far as possible).
- \sa absolutePath(), canonicalPath()
+ This method is shared with QUrl, so it doesn't deal with QDir::separator(),
+ nor does it remove the trailing slash, if any.
*/
-QString QDir::cleanPath(const QString &path)
+QString qt_normalizePathSegments(const QString &name, bool allowUncPaths)
{
- if (path.isEmpty())
- return path;
- QString name = path;
- QChar dir_separator = separator();
- if (dir_separator != QLatin1Char('/'))
- name.replace(dir_separator, QLatin1Char('/'));
-
int used = 0, levels = 0;
const int len = name.length();
QVarLengthArray<QChar> outVector(len);
@@ -2033,10 +2022,8 @@ QString QDir::cleanPath(const QString &path)
for (int i = 0, last = -1, iwrite = 0; i < len; ++i) {
if (p[i] == QLatin1Char('/')) {
while (i+1 < len && p[i+1] == QLatin1Char('/')) {
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
- if (!i)
+ if (allowUncPaths && i == 0)
break;
-#endif
i++;
}
bool eaten = false;
@@ -2099,8 +2086,6 @@ QString QDir::cleanPath(const QString &path)
eaten = true;
#endif
last = -1;
- } else if (last != -1 && i == len-1) {
- eaten = true;
} else {
levels++;
}
@@ -2126,6 +2111,36 @@ QString QDir::cleanPath(const QString &path)
}
QString ret = (used == len ? name : QString(out, used));
+ return ret;
+}
+
+/*!
+ Returns \a path with directory separators normalized (converted to "/") and
+ redundant ones removed, and "."s and ".."s resolved (as far as possible).
+
+ Symbolic links are kept. This function does not return the
+ canonical path, but rather the simplest version of the input.
+ For example, "./local" becomes "local", "local/../bin" becomes
+ "bin" and "/local/usr/../bin" becomes "/local/bin".
+
+ \sa absolutePath(), canonicalPath()
+*/
+QString QDir::cleanPath(const QString &path)
+{
+ if (path.isEmpty())
+ return path;
+ QString name = path;
+ QChar dir_separator = separator();
+ if (dir_separator != QLatin1Char('/'))
+ name.replace(dir_separator, QLatin1Char('/'));
+
+ bool allowUncPaths = false;
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
+ allowUncPaths = true;
+#endif
+
+ QString ret = qt_normalizePathSegments(name, allowUncPaths);
+
// Strip away last slash except for root directories
if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
#if defined (Q_OS_WIN)
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index c8a3f86137..1b06f3ec86 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -46,6 +46,8 @@
#include "qiodevice_p.h"
#include "qfile.h"
#include "qstringlist.h"
+
+#include <algorithm>
#include <limits.h>
#ifdef QIODEVICE_DEBUG
@@ -1686,7 +1688,7 @@ QDebug operator<<(QDebug debug, QIODevice::OpenMode modes)
if (modes & QIODevice::Unbuffered)
modeList << QLatin1String("Unbuffered");
}
- qSort(modeList);
+ std::sort(modeList.begin(), modeList.end());
debug << modeList.join(QLatin1Char('|'));
debug << ')';
return debug;
diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp
index bd36d36ac1..334c239c91 100644
--- a/src/corelib/io/qipaddress.cpp
+++ b/src/corelib/io/qipaddress.cpp
@@ -53,7 +53,7 @@ static QString number(quint8 val, int base = 10)
}
typedef QVarLengthArray<char, 64> Buffer;
-static bool checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end)
+static const QChar *checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end)
{
const ushort *const ubegin = reinterpret_cast<const ushort *>(begin);
const ushort *const uend = reinterpret_cast<const ushort *>(end);
@@ -64,11 +64,11 @@ static bool checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end)
while (src != uend) {
if (*src >= 0x7f)
- return false;
+ return reinterpret_cast<const QChar *>(src);
*dst++ = *src++;
}
*dst = '\0';
- return true;
+ return 0;
}
static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptLeadingZero);
@@ -76,7 +76,7 @@ bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end)
{
Q_ASSERT(begin != end);
Buffer buffer;
- if (!checkedToAscii(buffer, begin, end))
+ if (checkedToAscii(buffer, begin, end))
return false;
const char *ptr = buffer.data();
@@ -137,12 +137,23 @@ void toString(QString &appendTo, IPv4Address address)
% number(address);
}
-bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
+/*!
+ \internal
+ \since 5.0
+
+ Parses one IPv6 address from \a begin to \a end and stores the
+ representation in \a address. Returns null if everything was parsed
+ correctly, or the pointer to the first bad character where parsing failed.
+ If the parsing failed for a reason not related to a particular character,
+ returns \a end.
+*/
+const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
{
Q_ASSERT(begin != end);
Buffer buffer;
- if (!checkedToAscii(buffer, begin, end))
- return false;
+ const QChar *ret = checkedToAscii(buffer, begin, end);
+ if (ret)
+ return ret;
const char *ptr = buffer.data();
@@ -158,11 +169,11 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
}
// IPv4-in-IPv6 addresses are stricter in what they accept
if (dotCount != 0 && dotCount != 3)
- return false;
+ return end;
memset(address, 0, sizeof address);
if (colonCount == 2 && end - begin == 2) // "::"
- return true;
+ return 0;
// if there's a double colon ("::"), this is how many zeroes it means
int zeroWordsToFill;
@@ -174,7 +185,7 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
(ptr[end - begin - 2] == ':' && ptr[end - begin - 1] == ':')) {
zeroWordsToFill = 9 - colonCount;
} else if (colonCount < 2 || colonCount > 7) {
- return false;
+ return end;
} else {
zeroWordsToFill = 8 - colonCount;
}
@@ -183,18 +194,13 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
int pos = 0;
while (pos < 15) {
- const char *endptr;
- bool ok;
- quint64 ll = qstrtoull(ptr, &endptr, 16, &ok);
- quint16 x = ll;
-
- if (ptr == endptr) {
+ if (*ptr == ':') {
// empty field, we hope it's "::"
if (zeroWordsToFill < 1)
- return false;
+ return begin + (ptr - buffer.data());
if (pos == 0 || pos == colonCount * 2) {
if (ptr[0] == '\0' || ptr[1] != ':')
- return false;
+ return begin + (ptr - buffer.data());
++ptr;
}
pos += zeroWordsToFill * 2;
@@ -202,24 +208,30 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
++ptr;
continue;
}
+
+ const char *endptr;
+ bool ok;
+ quint64 ll = qstrtoull(ptr, &endptr, 16, &ok);
+ quint16 x = ll;
+
if (!ok || ll != x)
- return false;
+ return begin + (ptr - buffer.data());
if (*endptr == '.') {
// this could be an IPv4 address
// it's only valid in the last element
if (pos != 12)
- return false;
+ return begin + (ptr - buffer.data());
IPv4Address ip4;
if (!parseIp4Internal(ip4, ptr, false))
- return false;
+ return begin + (ptr - buffer.data());
address[12] = ip4 >> 24;
address[13] = ip4 >> 16;
address[14] = ip4 >> 8;
address[15] = ip4;
- return true;
+ return 0;
}
address[pos++] = x >> 8;
@@ -228,10 +240,10 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
if (*endptr == '\0')
break;
if (*endptr != ':')
- return false;
+ return begin + (endptr - buffer.data());
ptr = endptr + 1;
}
- return pos == 16;
+ return pos == 16 ? 0 : end;
}
static inline QChar toHex(uchar c)
diff --git a/src/corelib/io/qipaddress_p.h b/src/corelib/io/qipaddress_p.h
index d5c158d4d1..3059a1c205 100644
--- a/src/corelib/io/qipaddress_p.h
+++ b/src/corelib/io/qipaddress_p.h
@@ -63,7 +63,7 @@ typedef quint32 IPv4Address;
typedef quint8 IPv6Address[16];
Q_CORE_EXPORT bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end);
-Q_CORE_EXPORT bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end);
+Q_CORE_EXPORT const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end);
Q_CORE_EXPORT void toString(QString &appendTo, IPv4Address address);
Q_CORE_EXPORT void toString(QString &appendTo, IPv6Address address);
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 96cec568df..7f4d7f0313 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -533,7 +533,11 @@ void QProcessPrivate::Channel::clear()
MergedChannels before starting the process to activative
this feature. You also have the option of forwarding the output of
the running process to the calling, main process, by passing
- ForwardedChannels as the argument.
+ ForwardedChannels as the argument. It is also possible to forward
+ only one of the output channels - typically one would use
+ ForwardedErrorChannel, but ForwardedOutputChannel also exists.
+ Note that using channel forwarding is typically a bad idea in GUI
+ applications - you should present errors graphically instead.
Certain processes need special environment settings in order to
operate. You can set environment variables for your process by
@@ -604,8 +608,8 @@ void QProcessPrivate::Channel::clear()
/*!
\enum QProcess::ProcessChannelMode
- This enum describes the process channel modes of QProcess. Pass
- one of these values to setProcessChannelMode() to set the
+ This enum describes the process output channel modes of QProcess.
+ Pass one of these values to setProcessChannelMode() to set the
current read channel mode.
\value SeparateChannels QProcess manages the output of the
@@ -625,6 +629,17 @@ void QProcessPrivate::Channel::clear()
writes to its standard output and standard error will be written
to the standard output and standard error of the main process.
+ \value ForwardedErrorChannel QProcess manages the standard output
+ of the running process, but forwards its standard error onto the
+ main process. This reflects the typical use of command line tools
+ as filters, where the standard output is redirected to another
+ process or a file, while standard error is printed to the console
+ for diagnostic purposes.
+ (This value was introduced in Qt 5.2.)
+
+ \value ForwardedOutputChannel Complementary to ForwardedErrorChannel.
+ (This value was introduced in Qt 5.2.)
+
\note Windows intentionally suppresses output from GUI-only
applications to inherited consoles.
This does \e not apply to output redirected to files or pipes.
@@ -637,6 +652,26 @@ void QProcessPrivate::Channel::clear()
*/
/*!
+ \enum QProcess::InputChannelMode
+ \since 5.2
+
+ This enum describes the process input channel modes of QProcess.
+ Pass one of these values to setInputChannelMode() to set the
+ current write channel mode.
+
+ \value ManagedInputChannel QProcess manages the input of the running
+ process. This is the default input channel mode of QProcess.
+
+ \value ForwardedInputChannel QProcess forwards the input of the main
+ process onto the running process. The child process reads its standard
+ input from the same source as the main process.
+ Note that the main process must not try to read its standard input
+ while the child process is running.
+
+ \sa setInputChannelMode()
+*/
+
+/*!
\enum QProcess::ProcessError
This enum describes the different types of errors that are
@@ -764,6 +799,7 @@ QProcessPrivate::QProcessPrivate()
{
processChannel = QProcess::StandardOutput;
processChannelMode = QProcess::SeparateChannels;
+ inputChannelMode = QProcess::ManagedInputChannel;
processError = QProcess::UnknownError;
processState = QProcess::NotRunning;
pid = 0;
@@ -1229,6 +1265,34 @@ void QProcess::setProcessChannelMode(ProcessChannelMode mode)
}
/*!
+ \since 5.2
+
+ Returns the channel mode of the QProcess standard input channel.
+
+ \sa setInputChannelMode(), InputChannelMode
+*/
+QProcess::InputChannelMode QProcess::inputChannelMode() const
+{
+ Q_D(const QProcess);
+ return d->inputChannelMode;
+}
+
+/*!
+ \since 5.2
+
+ Sets the channel mode of the QProcess standard intput
+ channel to the \a mode specified.
+ This mode will be used the next time start() is called.
+
+ \sa inputChannelMode(), InputChannelMode
+*/
+void QProcess::setInputChannelMode(InputChannelMode mode)
+{
+ Q_D(QProcess);
+ d->inputChannelMode = mode;
+}
+
+/*!
Returns the current read channel of the QProcess.
\sa setReadChannel()
@@ -1317,6 +1381,10 @@ void QProcess::closeWriteChannel()
object will be in read-only mode (calling write() will result in
error).
+ To make the process read EOF right away, pass nullDevice() here.
+ This is cleaner than using closeWriteChannel() before writing any
+ data, because it can be set up prior to starting the process.
+
If the file \a fileName does not exist at the moment start() is
called or is not readable, starting the process will fail.
@@ -1340,6 +1408,10 @@ void QProcess::setStandardInputFile(const QString &fileName)
read channel is closed: reading from it using read() will always
fail, as will readAllStandardOutput().
+ To discard all standard output from the process, pass nullDevice()
+ here. This is more efficient than simply never reading the standard
+ output, as no QProcess buffers are filled.
+
If the file \a fileName doesn't exist at the moment start() is
called, it will be created. If it cannot be created, the starting
will fail.
@@ -2440,6 +2512,25 @@ QStringList QProcess::systemEnvironment()
*/
/*!
+ \since 5.2
+
+ \brief The null device of the operating system.
+
+ The returned file path uses native directory separators.
+
+ \sa QProcess::setStandardInputFile(), QProcess::setStandardOutputFile(),
+ QProcess::setStandardErrorFile()
+*/
+QString QProcess::nullDevice()
+{
+#ifdef Q_OS_WIN
+ return QStringLiteral("\\\\.\\NUL");
+#else
+ return QStringLiteral("/dev/null");
+#endif
+}
+
+/*!
\typedef Q_PID
\relates QProcess
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index 9da3e63f38..c0b3ab945e 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -124,7 +124,13 @@ public:
enum ProcessChannelMode {
SeparateChannels,
MergedChannels,
- ForwardedChannels
+ ForwardedChannels,
+ ForwardedOutputChannel,
+ ForwardedErrorChannel
+ };
+ enum InputChannelMode {
+ ManagedInputChannel,
+ ForwardedInputChannel
};
enum ExitStatus {
NormalExit,
@@ -149,6 +155,8 @@ public:
void setReadChannelMode(ProcessChannelMode mode);
ProcessChannelMode processChannelMode() const;
void setProcessChannelMode(ProcessChannelMode mode);
+ InputChannelMode inputChannelMode() const;
+ void setInputChannelMode(InputChannelMode mode);
ProcessChannel readChannel() const;
void setReadChannel(ProcessChannel channel);
@@ -209,6 +217,8 @@ public:
static QStringList systemEnvironment();
+ static QString nullDevice();
+
public Q_SLOTS:
void terminate();
void kill();
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index e96cb42f94..219bdf8200 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -302,6 +302,7 @@ public:
QProcess::ProcessChannel processChannel;
QProcess::ProcessChannelMode processChannelMode;
+ QProcess::InputChannelMode inputChannelMode;
QProcess::ProcessError processError;
QProcess::ProcessState processState;
QString workingDirectory;
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index e9957d2384..9868ea624a 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -807,19 +807,29 @@ pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **en
? i : SPAWN_FDCLOSED;
}
+ if (inputChannelMode == QProcess::ManagedInputChannel)
+ fd_map[0] = stdinChannel.pipe[0];
+ else
+ fd_map[0] = QT_FILENO(stdin);
+
switch (processChannelMode) {
case QProcess::ForwardedChannels:
- fd_map[0] = stdinChannel.pipe[0];
fd_map[1] = QT_FILENO(stdout);
fd_map[2] = QT_FILENO(stderr);
break;
+ case QProcess::ForwardedOutputChannel:
+ fd_map[1] = QT_FILENO(stdout);
+ fd_map[2] = stderrChannel.pipe[1];
+ break;
+ case QProcess::ForwardedErrorChannel:
+ fd_map[1] = stdoutChannel.pipe[1];
+ fd_map[2] = QT_FILENO(stderr);
+ break;
case QProcess::MergedChannels:
- fd_map[0] = stdinChannel.pipe[0];
fd_map[1] = stdoutChannel.pipe[1];
fd_map[2] = stdoutChannel.pipe[1];
break;
case QProcess::SeparateChannels:
- fd_map[0] = stdinChannel.pipe[0];
fd_map[1] = stdoutChannel.pipe[1];
fd_map[2] = stderrChannel.pipe[1];
break;
@@ -845,17 +855,19 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
Q_Q(QProcess);
- // copy the stdin socket (without closing on exec)
- qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0);
+ // copy the stdin socket if asked to (without closing on exec)
+ if (inputChannelMode != QProcess::ForwardedInputChannel)
+ qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0);
// copy the stdout and stderr if asked to
if (processChannelMode != QProcess::ForwardedChannels) {
- qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0);
+ if (processChannelMode != QProcess::ForwardedOutputChannel)
+ qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0);
// merge stdout and stderr if asked to
if (processChannelMode == QProcess::MergedChannels) {
qt_safe_dup2(fileno(stdout), fileno(stderr), 0);
- } else {
+ } else if (processChannelMode != QProcess::ForwardedErrorChannel) {
qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0);
}
}
@@ -1031,6 +1043,41 @@ static int qt_timeout_value(int msecs, int elapsed)
return timeout < 0 ? 0 : timeout;
}
+#ifdef Q_OS_BLACKBERRY
+// The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered
+// socket notifiers are disabled by a call to select. This is to rearm the standard streams.
+static int bb_select(QProcessPrivate *process, int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
+{
+ bool stdoutEnabled = false;
+ bool stderrEnabled = false;
+ bool stdinEnabled = false;
+
+ if (process->stdoutChannel.notifier && process->stdoutChannel.notifier->isEnabled()) {
+ stdoutEnabled = true;
+ process->stdoutChannel.notifier->setEnabled(false);
+ }
+ if (process->stderrChannel.notifier && process->stderrChannel.notifier->isEnabled()) {
+ stderrEnabled = true;
+ process->stderrChannel.notifier->setEnabled(false);
+ }
+ if (process->stdinChannel.notifier && process->stdinChannel.notifier->isEnabled()) {
+ stdinEnabled = true;
+ process->stdinChannel.notifier->setEnabled(false);
+ }
+
+ const int ret = select_msecs(nfds, fdread, fdwrite, timeout);
+
+ if (stdoutEnabled)
+ process->stdoutChannel.notifier->setEnabled(true);
+ if (stderrEnabled)
+ process->stderrChannel.notifier->setEnabled(true);
+ if (stdinEnabled)
+ process->stdinChannel.notifier->setEnabled(true);
+
+ return ret;
+}
+#endif // Q_OS_BLACKBERRY
+
bool QProcessPrivate::waitForStarted(int msecs)
{
Q_Q(QProcess);
@@ -1091,7 +1138,11 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
@@ -1163,8 +1214,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
- int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
+ int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
@@ -1230,8 +1285,12 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
- int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
+ int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index f16025752e..291ea319ec 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -155,28 +155,43 @@ bool QProcessPrivate::createChannel(Channel &channel)
if (channel.type == Channel::Normal) {
// we're piping this channel to our own process
- const bool isStdInChannel = (&channel == &stdinChannel);
- if (isStdInChannel || processChannelMode != QProcess::ForwardedChannels)
- qt_create_pipe(channel.pipe, isStdInChannel);
- else
- duplicateStdWriteChannel(channel.pipe, (&channel == &stdoutChannel) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
-
- if (processChannelMode != QProcess::ForwardedChannels) {
+ if (&channel == &stdinChannel) {
+ if (inputChannelMode != QProcess::ForwardedInputChannel) {
+ qt_create_pipe(channel.pipe, true);
+ } else {
+ channel.pipe[1] = INVALID_Q_PIPE;
+ HANDLE hStdReadChannel = GetStdHandle(STD_INPUT_HANDLE);
+ HANDLE hCurrentProcess = GetCurrentProcess();
+ DuplicateHandle(hCurrentProcess, hStdReadChannel, hCurrentProcess,
+ &channel.pipe[0], 0, TRUE, DUPLICATE_SAME_ACCESS);
+ }
+ } else {
QWindowsPipeReader *pipeReader = 0;
if (&channel == &stdoutChannel) {
- if (!stdoutReader) {
- stdoutReader = new QWindowsPipeReader(q);
- q->connect(stdoutReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput()));
+ if (processChannelMode != QProcess::ForwardedChannels
+ && processChannelMode != QProcess::ForwardedOutputChannel) {
+ if (!stdoutReader) {
+ stdoutReader = new QWindowsPipeReader(q);
+ q->connect(stdoutReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput()));
+ }
+ pipeReader = stdoutReader;
+ } else {
+ duplicateStdWriteChannel(channel.pipe, STD_OUTPUT_HANDLE);
}
- pipeReader = stdoutReader;
- } else if (&channel == &stderrChannel) {
- if (!stderrReader) {
- stderrReader = new QWindowsPipeReader(q);
- q->connect(stderrReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError()));
+ } else /* if (&channel == &stderrChannel) */ {
+ if (processChannelMode != QProcess::ForwardedChannels
+ && processChannelMode != QProcess::ForwardedErrorChannel) {
+ if (!stderrReader) {
+ stderrReader = new QWindowsPipeReader(q);
+ q->connect(stderrReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError()));
+ }
+ pipeReader = stderrReader;
+ } else {
+ duplicateStdWriteChannel(channel.pipe, STD_ERROR_HANDLE);
}
- pipeReader = stderrReader;
}
if (pipeReader) {
+ qt_create_pipe(channel.pipe, false);
pipeReader->setHandle(channel.pipe[0]);
pipeReader->startAsyncRead();
}
@@ -479,9 +494,12 @@ void QProcessPrivate::startProcess()
qDebug(" pass environment : %s", environment.isEmpty() ? "no" : "yes");
#endif
- // Forwarded channels must not set the CREATE_NO_WINDOW flag because this
- // will render the stdout/stderr handles we're passing useless.
- DWORD dwCreationFlags = (processChannelMode == QProcess::ForwardedChannels ? 0 : CREATE_NO_WINDOW);
+ // We cannot unconditionally set the CREATE_NO_WINDOW flag, because this
+ // will render the stdout/stderr handles connected to a console useless
+ // (this typically affects ForwardedChannels mode).
+ // However, we also do not want console tools launched from a GUI app to
+ // create new console windows (behavior consistent with UNIX).
+ DWORD dwCreationFlags = (GetConsoleWindow() ? 0 : CREATE_NO_WINDOW);
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
@@ -663,9 +681,8 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
if (pipeWriter && pipeWriter->waitForWrite(0))
timer.resetIncrements();
- if (processChannelMode != QProcess::ForwardedChannels
- && ((stdoutReader && stdoutReader->waitForReadyRead(0))
- || (stderrReader && stderrReader->waitForReadyRead(0))))
+ if ((stdoutReader && stdoutReader->waitForReadyRead(0))
+ || (stderrReader && stderrReader->waitForReadyRead(0)))
return true;
if (!pid)
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 5b4d4ec0d8..22eda87c36 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -3443,7 +3443,7 @@ void QSettings::setUserIniPath(const QString &dir)
\c XDG_CONFIG_HOME environment variable. The default SystemScope
paths on Unix and Mac OS X (\c /etc/xdg) can be overridden when
building the Qt library using the \c configure script's \c
- --sysconfdir flag (see QLibraryInfo for details).
+ -sysconfdir flag (see QLibraryInfo for details).
Setting the NativeFormat paths on Windows and Mac OS X has no
effect.
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index bd399f511e..ea917c90d9 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -347,6 +347,10 @@ QString QStandardPaths::displayName(StandardLocation type)
/*!
\fn void QStandardPaths::enableTestMode(bool testMode)
+ \obsolete Use QStandardPaths::setTestModeEnabled
+ */
+/*!
+ \fn void QStandardPaths::setTestModeEnabled(bool testMode)
If \a testMode is true, this enables a special "test mode" in
QStandardPaths, which changes writable locations
@@ -369,10 +373,17 @@ QString QStandardPaths::displayName(StandardLocation type)
static bool qsp_testMode = false;
+#if QT_DEPRECATED_SINCE(5, 2)
void QStandardPaths::enableTestMode(bool testMode)
{
qsp_testMode = testMode;
}
+#endif
+
+void QStandardPaths::setTestModeEnabled(bool testMode)
+{
+ qsp_testMode = testMode;
+}
/*!
\fn void QStandardPaths::isTestModeEnabled()
diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h
index d8b6d24f57..df9089ace7 100644
--- a/src/corelib/io/qstandardpaths.h
+++ b/src/corelib/io/qstandardpaths.h
@@ -89,7 +89,10 @@ public:
static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList());
- static void enableTestMode(bool testMode);
+#if QT_DEPRECATED_SINCE(5, 2)
+ static QT_DEPRECATED void enableTestMode(bool testMode);
+#endif
+ static void setTestModeEnabled(bool testMode);
static bool isTestModeEnabled();
private:
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index f2e1f9bbc7..9f9653ea94 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -65,7 +65,8 @@
unencoded representation is suitable for showing to users, but
the encoded representation is typically what you would send to
a web server. For example, the unencoded URL
- "http://b\\uuml\c{}hler.example.com" would be sent to the server as
+ "http://bühler.example.com/List of applicants.xml"
+ would be sent to the server as
"http://xn--bhler-kva.example.com/List%20of%20applicants.xml".
A URL can also be constructed piece by piece by calling
@@ -75,8 +76,10 @@
password, host and port. setUserInfo() sets the user name and
password at once.
- Call isValid() to check if the URL is valid. This can be done at
- any point during the constructing of a URL.
+ Call isValid() to check if the URL is valid. This can be done at any point
+ during the constructing of a URL. If isValid() returns false, you should
+ clear() the URL before proceeding, or start over by parsing a new URL with
+ setUrl().
Constructing a query is particularly convenient through the use of the \l
QUrlQuery class and its methods QUrlQuery::setQueryItems(),
@@ -101,13 +104,19 @@
toString(). This representation is appropriate for displaying a
URL to a user in unencoded form. The encoded form however, as
returned by toEncoded(), is for internal use, passing to web
- servers, mail clients and so on.
+ servers, mail clients and so on. Both forms are technically correct
+ and represent the same URL unambiguously -- in fact, passing either
+ form to QUrl's constructor or to setUrl() will yield the same QUrl
+ object.
QUrl conforms to the URI specification from
\l{RFC 3986} (Uniform Resource Identifier: Generic Syntax), and includes
scheme extensions from \l{RFC 1738} (Uniform Resource Locators). Case
folding rules in QUrl conform to \l{RFC 3491} (Nameprep: A Stringprep
- Profile for Internationalized Domain Names (IDN)).
+ Profile for Internationalized Domain Names (IDN)). It is also compatible with the
+ \l{http://freedesktop.org/wiki/Specifications/file-uri-spec/}{file URI specification}
+ from freedesktop.org, provided that the locale encodes file names using
+ UTF-8 (required by IDN).
\section2 Error checking
@@ -170,6 +179,8 @@
of a percent-encoded sequence. This mode is only valid for the
setters setting components of a URL; it is not permitted in
the QUrl constructor, in fromEncoded() or in setUrl().
+ For more information on this mode, see the documentation for
+ QUrl::FullyDecoded.
In TolerantMode, the parser has the following behaviour:
@@ -186,11 +197,12 @@
\li Reserved and unreserved characters: An encoded URL should only
contain a few characters as literals; all other characters should
be percent-encoded. In TolerantMode, these characters will be
- automatically percent-encoded where they are not allowed:
+ accepted if they are found in the URL:
space / double-quote / "<" / ">" / "\" /
"^" / "`" / "{" / "|" / "}"
Those same characters can be decoded again by passing QUrl::DecodeReserved
- to toString() or toEncoded().
+ to toString() or toEncoded(). In the getters of individual components,
+ those characters are often returned in decoded form.
\endlist
@@ -225,9 +237,14 @@
\value RemoveQuery The query part of the URL (following a '?' character)
is removed.
\value RemoveFragment
+ \value RemoveFilename The filename (i.e. everything after the last '/' in the path) is removed.
+ The trailing '/' is kept, unless StripTrailingSlash is set.
+ Only valid if RemovePath is not set.
\value PreferLocalFile If the URL is a local file according to isLocalFile()
and contains no query or fragment, a local file path is returned.
\value StripTrailingSlash The trailing slash is removed if one is present.
+ \value NormalizePathSegments Modifies the path to remove redundant directory separators,
+ and to resolve "."s and ".."s (as far as possible).
Note that the case folding rules in \l{RFC 3491}{Nameprep}, which QUrl
conforms to, require host names to always be converted to lower case,
@@ -263,11 +280,15 @@
would appear in the URL when the full URL is
represented as text. The delimiters are affected
by this option change from component to component.
+ This flag has no effect in toString() or toEncoded().
- \value EncodeReserved Leave the US-ASCII reserved characters in their encoded
- forms.
+ \value EncodeReserved Leave US-ASCII characters not permitted in the URL by
+ the specification in their encoded form. This is the
+ default on toString() and toEncoded().
- \value DecodeReserved Decode the US-ASCII reserved characters.
+ \value DecodeReserved Decode the US-ASCII characters that the URL specification
+ does not allow to appear in the URL. This is the
+ default on the getters of individual components.
\value FullyEncoded Leave all characters in their properly-encoded form,
as this component would appear as part of a URL. When
@@ -279,28 +300,65 @@
components of the URL, this decodes every percent
encoding sequence, including control characters (U+0000
to U+001F) and UTF-8 sequences found in percent-encoded form.
- Note: if the component contains non-US-ASCII sequences
- that aren't valid UTF-8 sequences, the behaviour is
- undefined since QString cannot represent those values
- (data will be lost!)
- This mode is should not be used in functions where more
- than one URL component is returned (userInfo() and authority())
- and it is not allowed in url() and toString().
+ Use of this mode may cause data loss, see below for more information.
The values of EncodeReserved and DecodeReserved should not be used together
- in one call. The behaviour is undefined if that happens. They are provided
- as separate values because the behaviour of the "pretty mode" with regards
+ in one call. The behavior is undefined if that happens. They are provided
+ as separate values because the behavior of the "pretty mode" with regards
to reserved characters is different on certain components and specially on
the full URL.
- The FullyDecoded mode is similar to the behaviour of the functions
- returning QString in Qt 4.x, including the fact that they will most likely
- cause data loss if the component in question contains a non-UTF-8
- percent-encoded sequence. Fortunately, those cases aren't common, so this
- mode should be used when the component in question is used in a non-URL
- context. For example, in an FTP client application, the path to the remote
- file could be stored in a QUrl object, and the string to be transmitted to
- the FTP server should be obtained using this flag.
+ \section2 Full decoding
+
+ The FullyDecoded mode is similar to the behavior of the functions returning
+ QString in Qt 4.x, in that every character represents itself and never has
+ any special meaning. This is true even for the percent character ('%'),
+ which should be interpreted to mean a literal percent, not the beginning of
+ a percent-encoded sequence. The same actual character, in all other
+ decoding modes, is represented by the sequence "%25".
+
+ Whenever re-applying data obtained with QUrl::FullyDecoded into a QUrl,
+ care must be taken to use the QUrl::DecodedMode parameter to the setters
+ (like setPath() and setUserName()). Failure to do so may cause
+ re-interpretation of the percent character ('%') as the beginning of a
+ percent-encoded sequence.
+
+ This mode is quite useful when portions of a URL are used in a non-URL
+ context. For example, to extract the username, password or file paths in an
+ FTP client application, the FullyDecoded mode should be used.
+
+ This mode should be used with care, since there are two conditions that
+ cannot be reliably represented in the returned QString. They are:
+
+ \list
+ \li \b{Non-UTF-8 sequences:} URLs may contain sequences of
+ percent-encoded characters that do not form valid UTF-8 sequences. Since
+ URLs need to be decoded using UTF-8, any decoder failure will result in
+ the QString containing one or more replacement characters where the
+ sequence existed.
+
+ \li \b{Encoded delimiters:} URLs are also allowed to make a distinction
+ between a delimiter found in its literal form and its equivalent in
+ percent-encoded form. This is most commonly found in the query, but is
+ permitted in most parts of the URL.
+ \endlist
+
+ The following example illustrates the problem:
+
+ \code
+ QUrl original("http://example.com/?q=a%2B%3Db%26c");
+ QUrl copy(original);
+ copy.setQuery(copy.query(QUrl::FullyDecoded), QUrl::DecodedMode);
+
+ qDebug() << original.toString(); // prints: http://example.com/?q=a%2B%3Db%26c
+ qDebug() << copy.toString(); // prints: http://example.com/?q=a+=b&c
+ \endcode
+
+ If the two URLs were used via HTTP GET, the interpretation by the web
+ server would probably be different. In the first case, it would interpret
+ as one parameter, with a key of "q" and value "a+=b&c". In the second
+ case, it would probably interpret as two parameters, one with a key of "q"
+ and value "a =b", and the second with a key "c" and no value.
\sa QUrl::FormattingOptions
*/
@@ -321,6 +379,7 @@
#endif
QT_BEGIN_NAMESPACE
+extern QString qt_normalizePathSegments(const QString &name, bool allowUncPaths); // qdir.cpp
inline static bool isHex(char c)
{
@@ -368,6 +427,7 @@ public:
InvalidRegNameError = Host << 8,
InvalidIPv4AddressError,
InvalidIPv6AddressError,
+ InvalidCharacterInIPv6Error,
InvalidIPvFutureError,
HostMissingEndBracket,
@@ -418,7 +478,7 @@ public:
void appendHost(QString &appendTo, QUrl::FormattingOptions options) const;
void appendPath(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
void appendQuery(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
- void appendFragment(QString &appendTo, QUrl::FormattingOptions options) const;
+ void appendFragment(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
// the "end" parameters are like STL iterators: they point to one past the last valid element
bool setScheme(const QString &value, int len, bool doSetError);
@@ -513,7 +573,7 @@ inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, in
error->position = supplement;
}
-// From RFC 3896, Appendix A Collected ABNF for URI
+// From RFC 3986, Appendix A Collected ABNF for URI
// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
//[...]
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
@@ -541,46 +601,62 @@ inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, in
// the path component has a complex ABNF that basically boils down to
// slash-separated segments of "pchar"
-// The above is the strict definition of the URL components and it is what we
-// return encoded as FullyEncoded. However, we store the equivalent to
-// PrettyDecoded internally, as that is the default formatting mode and most
-// likely to be used. PrettyDecoded decodes spaces, unicode sequences and
-// unambiguous delimiters.
+// The above is the strict definition of the URL components and we mostly
+// adhere to it, with few exceptions. QUrl obeys the following behavior:
+// - percent-encoding sequences always use uppercase HEXDIG;
+// - unreserved characters are *always* decoded, no exceptions;
+// - the space character and bytes with the high bit set are controlled by
+// the EncodeSpaces and EncodeUnicode bits;
+// - control characters, the percent sign itself, and bytes with the high
+// bit set that don't form valid UTF-8 sequences are always encoded,
+// except in FullyDecoded mode;
+// - sub-delims are always left alone, except in FullyDecoded mode;
+// - gen-delim change behavior depending on which section of the URL (or
+// the entire URL) we're looking at; see below;
+// - characters not mentioned above, like "<", and ">", are usually
+// decoded in individual sections of the URL, but encoded when the full
+// URL is put together (we can change on subjective definition of
+// "pretty").
//
-// An ambiguous delimiter is a delimiter that, if appeared decoded, would be
-// interpreted as the beginning of a new component. The exact delimiters that
-// match that definition change according to the use. When each field is
-// considered in isolation from the rest, there are no ambiguities. In other
-// words, we always store the most decoded form (except for the query, see
-// below).
+// The behavior for the delimiters bears some explanation. The spec says in
+// section 2.2:
+// URIs that differ in the replacement of a reserved character with its
+// corresponding percent-encoded octet are not equivalent.
+// (note: QUrl API mistakenly uses the "reserved" term, so we will refer to
+// them here as "delimiters").
//
-// The ambiguities arise when components are put together. From last to first
-// component of a full URL, the ambiguities are:
-// - fragment: none, since it's the last.
-// - query: the "#" character is ambiguous, as it starts the fragment. In
-// addition, the "+" character is treated specially, as should be both
-// intra-query delimiters. Since we don't know which ones they are, we
-// keep all reserved characters untouched.
-// - path: the "#" and "?" characters are ambigous. In addition to them,
-// the slash itself is considered special.
+// For that reason, we cannot encode delimiters found in decoded form and we
+// cannot decode the ones found in encoded form if that would change the
+// interpretation. Conversely, we *can* perform the transformation if it would
+// not change the interpretation. From the last component of a URL to the first,
+// here are the gen-delims we can unambiguously transform when the field is
+// taken in isolation:
+// - fragment: none, since it's the last
+// - query: "#" is unambiguous
+// - path: "#" and "?" are unambiguous
// - host: completely special but never ambiguous, see setHost() below.
-// - password: the "#", "?", "/", "[", "]" and "@" characters are ambiguous
-// - username: the "#", "?", "/", "[", "]", "@", and ":" characters are ambiguous
+// - password: the "#", "?", "/", "[", "]" and "@" characters are unambiguous
+// - username: the "#", "?", "/", "[", "]", "@", and ":" characters are unambiguous
// - scheme: doesn't accept any delimiter, see setScheme() below.
//
-// When the authority component is considered in isolation, the ambiguities of
-// its components are:
-// - host: special, never ambiguous
-// - password: "[", "]", "@" are ambiguous
-// - username: "[", "]", "@", ":" are ambiguous
+// Internally, QUrl stores each component in the format that corresponds to the
+// default mode (PrettyDecoded). It deviates from the "strict" FullyEncoded
+// mode in the following way:
+// - spaces are decoded
+// - valid UTF-8 sequences are decoded
+// - gen-delims that can be unambiguously transformed are decoded
+// - characters controlled by DecodeReserved are often decoded, though this behavior
+// can change depending on the subjective definition of "pretty"
//
-// Finally, when the userinfo is considered in isolation, the ambiguities of its
-// components are:
-// - password: none, since it's the last
-// - username: ":" is ambiguous
+// Note that the list of gen-delims that we can transform is different for the
+// user info (user name + password) and the authority (user info + host +
+// port).
+
// list the recoding table modifications to be used with the recodeFromUser and
-// appendToUser functions, according to the rules above.
+// appendToUser functions, according to the rules above. Spaces and UTF-8
+// sequences are handled outside the tables.
+
// the encodedXXX tables are run with the delimiters set to "leave" by default;
// the decodedXXX tables are run with the delimiters set to "decode" by default
// (except for the query, which doesn't use these functions)
@@ -589,103 +665,88 @@ inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, in
#define leave(x) ushort(0x100 | (x))
#define encode(x) ushort(0x200 | (x))
-static const ushort encodedUserNameActions[] = {
- // first field, everything must be encoded, including the ":"
- // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
- encode('/'), // 0
- encode('?'), // 1
- encode('#'), // 2
- encode('['), // 3
- encode(']'), // 4
- encode('@'), // 5
- encode(':'), // 6
- 0
-};
-static const ushort * const decodedUserNameInAuthorityActions = encodedUserNameActions + 3;
-static const ushort * const decodedUserNameInUserInfoActions = encodedUserNameActions + 6;
-static const ushort * const decodedUserNameInUrlActions = encodedUserNameActions;
-static const ushort * const decodedUserNameInIsolationActions = 0;
-
-static const ushort encodedPasswordActions[] = {
- // same as encodedUserNameActions, but decode ":"
- // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
- encode('/'), // 0
- encode('?'), // 1
- encode('#'), // 2
- encode('['), // 3
- encode(']'), // 4
- encode('@'), // 5
- 0
-};
-static const ushort * const decodedPasswordInAuthorityActions = encodedPasswordActions + 3;
-static const ushort * const decodedPasswordInUserInfoActions = 0;
-static const ushort * const decodedPasswordInUrlActions = encodedPasswordActions;
-static const ushort * const decodedPasswordInIsolationActions = 0;
-
-static const ushort encodedPathActions[] = {
- // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
- encode('['), // 0
- encode(']'), // 1
- encode('?'), // 2
- encode('#'), // 3
- leave('/'), // 4
- 0
-};
-static const ushort decodedPathInUrlActions[] = {
- decode('{'), // 0
- decode('}'), // 1
- encode('?'), // 2
- encode('#'), // 3
- leave('/'), // 4
+static const ushort userNameInIsolation[] = {
+ decode(':'), // 0
+ decode('@'), // 1
+ decode(']'), // 2
+ decode('['), // 3
+ decode('/'), // 4
+ decode('?'), // 5
+ decode('#'), // 6
+
+ decode('"'), // 7
+ decode('<'),
+ decode('>'),
+ decode('^'),
+ decode('\\'),
+ decode('|'),
+ decode('{'),
+ decode('}'),
0
};
-static const ushort * const decodedPathInIsolationActions = encodedPathActions + 4; // leave('/')
-
-static const ushort encodedFragmentActions[] = {
- // fragment = *( pchar / "/" / "?" )
- // gen-delims permitted: ":" / "@" / "/" / "?"
- // -> must encode: "[" / "]" / "#"
- // HOWEVER: we allow "#" to remain decoded
- decode('#'), // 0
- decode(':'), // 1
- decode('@'), // 2
- decode('/'), // 3
- decode('?'), // 4
- encode('['), // 5
- encode(']'), // 6
+static const ushort * const passwordInIsolation = userNameInIsolation + 1;
+static const ushort * const pathInIsolation = userNameInIsolation + 5;
+static const ushort * const queryInIsolation = userNameInIsolation + 6;
+static const ushort * const fragmentInIsolation = userNameInIsolation + 7;
+
+static const ushort userNameInUserInfo[] = {
+ encode(':'), // 0
+ decode('@'), // 1
+ decode(']'), // 2
+ decode('['), // 3
+ decode('/'), // 4
+ decode('?'), // 5
+ decode('#'), // 6
+
+ decode('"'), // 7
+ decode('<'),
+ decode('>'),
+ decode('^'),
+ decode('\\'),
+ decode('|'),
+ decode('{'),
+ decode('}'),
0
};
-//static const ushort * const decodedFragmentInUrlActions = 0;
-static const ushort * const decodedFragmentInIsolationActions = 0;
-
-// the query is handled specially: the decodedQueryXXX tables are run with
-// the delimiters set to "leave" by default and the others set to "encode"
-static const ushort encodedQueryActions[] = {
- // query = *( pchar / "/" / "?" )
- // gen-delims permitted: ":" / "@" / "/" / "?"
- // HOWEVER: we leave alone them alone, plus "[" and "]"
- // -> must encode: "#"
- encode('#'), // 0
- 0
-};
-static const ushort decodedQueryInIsolationActions[] = {
- decode('"'), // 0
- decode('<'), // 1
- decode('>'), // 2
- decode('^'), // 3
- decode('\\'),// 4
- decode('|'), // 5
- decode('{'), // 6
- decode('}'), // 7
- decode('#'), // 8
+static const ushort * const passwordInUserInfo = userNameInUserInfo + 1;
+
+static const ushort userNameInAuthority[] = {
+ encode(':'), // 0
+ encode('@'), // 1
+ encode(']'), // 2
+ encode('['), // 3
+ decode('/'), // 4
+ decode('?'), // 5
+ decode('#'), // 6
+
+ decode('"'), // 7
+ decode('<'),
+ decode('>'),
+ decode('^'),
+ decode('\\'),
+ decode('|'),
+ decode('{'),
+ decode('}'),
0
};
-static const ushort decodedQueryInUrlActions[] = {
- decode('{'), // 6
- decode('}'), // 7
- encode('#'), // 8
+static const ushort * const passwordInAuthority = userNameInAuthority + 1;
+
+static const ushort userNameInUrl[] = {
+ encode(':'), // 0
+ encode('@'), // 1
+ encode(']'), // 2
+ encode('['), // 3
+ encode('/'), // 4
+ encode('?'), // 5
+ encode('#'), // 6
+
+ // no need to list encode(x) for the other characters
0
};
+static const ushort * const passwordInUrl = userNameInUrl + 1;
+static const ushort * const pathInUrl = userNameInUrl + 5;
+static const ushort * const queryInUrl = userNameInUrl + 6;
+static const ushort * const fragmentInUrl = userNameInUrl + 6;
static inline void parseDecodedComponent(QString &data)
{
@@ -698,33 +759,22 @@ recodeFromUser(const QString &input, const ushort *actions, int from, int to)
QString output;
const QChar *begin = input.constData() + from;
const QChar *end = input.constData() + to;
- if (qt_urlRecode(output, begin, end,
- QUrl::DecodeReserved, actions))
+ if (qt_urlRecode(output, begin, end, 0, actions))
return output;
return input.mid(from, to - from);
}
-// appendXXXX functions:
-// the internal value is stored in its most decoded form, so that case is easy.
-// DecodeUnicode and DecodeSpaces are handled by qt_urlRecode.
-// That leaves these functions to handle two cases related to delimiters:
-// 1) encoded encodedXXXX tables
-// 2) decoded decodedXXXX tables
+// appendXXXX functions: copy from the internal form to the external, user form.
+// the internal value is stored in its PrettyDecoded form, so that case is easy.
static inline void appendToUser(QString &appendTo, const QString &value, QUrl::FormattingOptions options,
- const ushort *encodedActions, const ushort *decodedActions)
+ const ushort *actions)
{
if (options == QUrl::PrettyDecoded) {
appendTo += value;
return;
}
- const ushort *actions = 0;
- if (options & QUrl::EncodeDelimiters)
- actions = encodedActions;
- else
- actions = decodedActions;
-
if (!qt_urlRecode(appendTo, value.constData(), value.constEnd(), options, actions))
appendTo += value;
}
@@ -751,31 +801,32 @@ inline void QUrlPrivate::appendUserInfo(QString &appendTo, QUrl::FormattingOptio
const ushort *userNameActions;
const ushort *passwordActions;
if (options & QUrl::EncodeDelimiters) {
- userNameActions = encodedUserNameActions;
- passwordActions = encodedPasswordActions;
+ userNameActions = userNameInUrl;
+ passwordActions = passwordInUrl;
} else {
switch (appendingTo) {
case UserInfo:
- userNameActions = decodedUserNameInUserInfoActions;
- passwordActions = decodedPasswordInUserInfoActions;
+ userNameActions = userNameInUserInfo;
+ passwordActions = passwordInUserInfo;
break;
case Authority:
- userNameActions = decodedUserNameInAuthorityActions;
- passwordActions = decodedPasswordInAuthorityActions;
+ userNameActions = userNameInAuthority;
+ passwordActions = passwordInAuthority;
break;
case FullUrl:
+ userNameActions = userNameInUrl;
+ passwordActions = passwordInUrl;
+ break;
+
default:
- userNameActions = decodedUserNameInUrlActions;
- passwordActions = decodedPasswordInUrlActions;
+ // can't happen
+ Q_UNREACHABLE();
break;
}
}
- if ((options & QUrl::EncodeReserved) == 0)
- options |= QUrl::DecodeReserved;
-
if (!qt_urlRecode(appendTo, userName.constData(), userName.constEnd(), options, userNameActions))
appendTo += userName;
if (options & QUrl::RemovePassword || !hasPassword()) {
@@ -789,51 +840,52 @@ inline void QUrlPrivate::appendUserInfo(QString &appendTo, QUrl::FormattingOptio
inline void QUrlPrivate::appendUserName(QString &appendTo, QUrl::FormattingOptions options) const
{
- appendToUser(appendTo, userName, options, encodedUserNameActions, decodedUserNameInIsolationActions);
+ // only called from QUrl::userName()
+ appendToUser(appendTo, userName, options,
+ options & QUrl::EncodeDelimiters ? userNameInUrl : userNameInIsolation);
}
inline void QUrlPrivate::appendPassword(QString &appendTo, QUrl::FormattingOptions options) const
{
- appendToUser(appendTo, password, options, encodedPasswordActions, decodedPasswordInIsolationActions);
+ // only called from QUrl::password()
+ appendToUser(appendTo, password, options,
+ options & QUrl::EncodeDelimiters ? passwordInUrl : passwordInIsolation);
}
inline void QUrlPrivate::appendPath(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
{
- if (appendingTo != Path && !(options & QUrl::EncodeDelimiters)) {
- if (!qt_urlRecode(appendTo, path.constData(), path.constEnd(), options, decodedPathInUrlActions))
- appendTo += path;
-
- } else {
- appendToUser(appendTo, path, options, encodedPathActions, decodedPathInIsolationActions);
+ QString thePath = path;
+ if (options & QUrl::NormalizePathSegments) {
+ thePath = qt_normalizePathSegments(path, false);
}
+ if (options & QUrl::RemoveFilename) {
+ const int slash = path.lastIndexOf(QLatin1Char('/'));
+ if (slash == -1)
+ return;
+ thePath = path.left(slash+1);
+ }
+ // check if we need to remove trailing slashes
+ if (options & QUrl::StripTrailingSlash) {
+ while (thePath.length() > 1 && thePath.endsWith(QLatin1Char('/')))
+ thePath.chop(1);
+ }
+
+ appendToUser(appendTo, thePath, options,
+ appendingTo == FullUrl || options & QUrl::EncodeDelimiters ? pathInUrl : pathInIsolation);
+
}
-inline void QUrlPrivate::appendFragment(QString &appendTo, QUrl::FormattingOptions options) const
+inline void QUrlPrivate::appendFragment(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
{
- appendToUser(appendTo, fragment, options, encodedFragmentActions, decodedFragmentInIsolationActions);
+ appendToUser(appendTo, fragment, options,
+ options & QUrl::EncodeDelimiters ? fragmentInUrl :
+ appendingTo == FullUrl ? 0 : fragmentInIsolation);
}
inline void QUrlPrivate::appendQuery(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
{
- // almost the same code as the previous functions
- // except we prefer not to touch the delimiters
- if (options == QUrl::PrettyDecoded && appendingTo == Query) {
- appendTo += query;
- return;
- }
-
- const ushort *actions = 0;
- if (options & QUrl::EncodeDelimiters) {
- actions = encodedQueryActions;
- } else {
- // reset to default qt_urlRecode behaviour (leave delimiters alone)
- options |= QUrl::EncodeDelimiters;
- actions = appendingTo == Query ? decodedQueryInIsolationActions : decodedQueryInUrlActions;
- }
-
- if (!qt_urlRecode(appendTo, query.constData(), query.constData() + query.length(),
- options, actions))
- appendTo += query;
+ appendToUser(appendTo, query, options,
+ appendingTo == FullUrl || options & QUrl::EncodeDelimiters ? queryInUrl : queryInIsolation);
}
// setXXX functions
@@ -978,42 +1030,31 @@ inline void QUrlPrivate::setUserInfo(const QString &userInfo, int from, int end)
inline void QUrlPrivate::setUserName(const QString &value, int from, int end)
{
sectionIsPresent |= UserName;
- userName = recodeFromUser(value, decodedUserNameInIsolationActions, from, end);
+ userName = recodeFromUser(value, userNameInIsolation, from, end);
}
inline void QUrlPrivate::setPassword(const QString &value, int from, int end)
{
sectionIsPresent |= Password;
- password = recodeFromUser(value, decodedPasswordInIsolationActions, from, end);
+ password = recodeFromUser(value, passwordInIsolation, from, end);
}
inline void QUrlPrivate::setPath(const QString &value, int from, int end)
{
// sectionIsPresent |= Path; // not used, save some cycles
- path = recodeFromUser(value, decodedPathInIsolationActions, from, end);
+ path = recodeFromUser(value, pathInIsolation, from, end);
}
inline void QUrlPrivate::setFragment(const QString &value, int from, int end)
{
sectionIsPresent |= Fragment;
- fragment = recodeFromUser(value, decodedFragmentInIsolationActions, from, end);
+ fragment = recodeFromUser(value, fragmentInIsolation, from, end);
}
inline void QUrlPrivate::setQuery(const QString &value, int from, int iend)
{
sectionIsPresent |= Query;
-
- // use the default actions for the query (don't set QUrl::DecodeAllDelimiters)
- QString output;
- const QChar *begin = value.constData() + from;
- const QChar *end = value.constData() + iend;
-
- // leave delimiters alone but decode the rest
- if (qt_urlRecode(output, begin, end, QUrl::EncodeDelimiters,
- decodedQueryInIsolationActions))
- query = output;
- else
- query = value.mid(from, iend - from);
+ query = recodeFromUser(value, queryInIsolation, from, iend);
}
// Host handling
@@ -1048,8 +1089,11 @@ inline void QUrlPrivate::setQuery(const QString &value, int from, int iend)
inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions options) const
{
- // this is the only flag that matters
- options &= QUrl::EncodeUnicode;
+ // EncodeUnicode is the only flag that matters
+ if ((options & QUrl::FullyDecoded) == QUrl::FullyDecoded)
+ options = 0;
+ else
+ options &= QUrl::EncodeUnicode;
if (host.isEmpty())
return;
if (host.at(0).unicode() == '[') {
@@ -1059,7 +1103,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o
// this is either an IPv4Address or a reg-name
// if it is a reg-name, it is already stored in Unicode form
if (options == QUrl::EncodeUnicode)
- appendTo += qt_ACE_do(host, ToAceOnly);
+ appendTo += qt_ACE_do(host, ToAceOnly, AllowLeadingDot);
else
appendTo += host;
}
@@ -1067,7 +1111,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o
// the whole IPvFuture is passed and parsed here, including brackets;
// returns null if the parsing was successful, or the QChar of the first failure
-static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar *end)
+static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode)
{
// IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
static const char acceptable[] =
@@ -1076,19 +1120,25 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
"-._~"; // unreserved
// the brackets and the "v" have been checked
+ const QChar *const origBegin = begin;
if (begin[3].unicode() != '.')
return &begin[3];
- if ((begin[2].unicode() >= 'A' && begin[2].unicode() >= 'F') ||
+ if ((begin[2].unicode() >= 'A' && begin[2].unicode() <= 'F') ||
(begin[2].unicode() >= 'a' && begin[2].unicode() <= 'f') ||
(begin[2].unicode() >= '0' && begin[2].unicode() <= '9')) {
// this is so unlikely that we'll just go down the slow path
// decode the whole string, skipping the "[vH." and "]" which we already know to be there
host += QString::fromRawData(begin, 4);
+
+ // uppercase the version, if necessary
+ if (begin[2].unicode() >= 'a')
+ host[host.length() - 2] = begin[2].unicode() - 0x20;
+
begin += 4;
--end;
QString decoded;
- if (qt_urlRecode(decoded, begin, end, QUrl::FullyEncoded, 0)) {
+ if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, QUrl::FullyDecoded, 0)) {
begin = decoded.constBegin();
end = decoded.constEnd();
}
@@ -1103,37 +1153,44 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
else if (begin->unicode() < 0x80 && strchr(acceptable, begin->unicode()) != 0)
host += *begin;
else
- return begin;
+ return decoded.isEmpty() ? begin : &origBegin[2];
}
host += QLatin1Char(']');
return 0;
}
- return &begin[2];
+ return &origBegin[2];
}
// ONLY the IPv6 address is parsed here, WITHOUT the brackets
-static bool parseIp6(QString &host, const QChar *begin, const QChar *end)
+static const QChar *parseIp6(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode)
{
QIPAddressUtils::IPv6Address address;
- if (!QIPAddressUtils::parseIp6(address, begin, end)) {
+ const QChar *ret = QIPAddressUtils::parseIp6(address, begin, end);
+ if (ret) {
+ // this struct is kept in automatic storage because it's only 4 bytes
+ const ushort decodeColon[] = { decode(':'), 0 };
+
// IPv6 failed parsing, check if it was a percent-encoded character in
// the middle and try again
QString decoded;
- if (!qt_urlRecode(decoded, begin, end, QUrl::FullyEncoded, 0)) {
- // no transformation, nothing to re-parse
- return false;
+ if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, 0, decodeColon)) {
+ // recurse
+ // if the parsing fails again, the qt_urlRecode above will return 0
+ ret = parseIp6(host, decoded.constBegin(), decoded.constEnd(), mode);
+
+ // we can't return ret, otherwise it would be dangling
+ return ret ? end : 0;
}
- // recurse
- // if the parsing fails again, the qt_urlRecode above will return 0
- return parseIp6(host, decoded.constBegin(), decoded.constEnd());
+ // no transformation, nothing to re-parse
+ return ret;
}
host.reserve(host.size() + (end - begin));
host += QLatin1Char('[');
QIPAddressUtils::toString(host, address);
host += QLatin1Char(']');
- return true;
+ return 0;
}
inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl::ParsingMode mode)
@@ -1157,17 +1214,22 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl:
}
if (len > 5 && begin[1].unicode() == 'v') {
- const QChar *c = parseIpFuture(host, begin, end);
+ const QChar *c = parseIpFuture(host, begin, end, mode);
if (c)
setError(InvalidIPvFutureError, value, c - value.constData());
return !c;
+ } else if (begin[1].unicode() == 'v') {
+ setError(InvalidIPvFutureError, value, from);
}
- if (parseIp6(host, begin + 1, end - 1))
+ const QChar *c = parseIp6(host, begin + 1, end - 1, mode);
+ if (!c)
return true;
- setError(begin[1].unicode() == 'v' ? InvalidIPvFutureError : InvalidIPv6AddressError,
- value, from);
+ if (c == end - 1)
+ setError(InvalidIPv6AddressError, value, from);
+ else
+ setError(InvalidCharacterInIPv6Error, value, c - value.constData());
return false;
}
@@ -1194,7 +1256,7 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl:
// check for percent-encoding first
QString s;
- if (mode == QUrl::TolerantMode && qt_urlRecode(s, begin, end, QUrl::DecodeReserved, 0)) {
+ if (mode == QUrl::TolerantMode && qt_urlRecode(s, begin, end, 0, 0)) {
// something was decoded
// anything encoded left?
int pos = s.indexOf(QChar(0x25)); // '%'
@@ -1207,7 +1269,7 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl:
return setHost(s, 0, s.length(), QUrl::StrictMode);
}
- s = qt_ACE_do(QString::fromRawData(begin, len), NormalizeAce);
+ s = qt_ACE_do(QString::fromRawData(begin, len), NormalizeAce, ForbidLeadingDot);
if (s.isEmpty()) {
setError(InvalidRegNameError, value);
return false;
@@ -1583,87 +1645,6 @@ inline void QUrlPrivate::validate() const
}
}
}
-
-inline const QByteArray &QUrlPrivate::normalized() const
-{
- if (QURL_HASFLAG(stateFlags, QUrlPrivate::Normalized))
- return encodedNormalized;
-
- QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
- QURL_SETFLAG(that->stateFlags, QUrlPrivate::Normalized);
-
- QUrlPrivate tmp = *this;
- tmp.scheme = tmp.scheme.toLower();
- tmp.host = tmp.canonicalHost();
-
- // ensure the encoded and normalized parts of the URL
- tmp.ensureEncodedParts();
- if (tmp.encodedUserName.contains('%'))
- q_normalizePercentEncoding(&tmp.encodedUserName, userNameExcludeChars);
- if (tmp.encodedPassword.contains('%'))
- q_normalizePercentEncoding(&tmp.encodedPassword, passwordExcludeChars);
- if (tmp.encodedFragment.contains('%'))
- q_normalizePercentEncoding(&tmp.encodedFragment, fragmentExcludeChars);
-
- if (tmp.encodedPath.contains('%')) {
- // the path is a bit special:
- // the slashes shouldn't be encoded or decoded.
- // They should remain exactly like they are right now
- //
- // treat the path as a slash-separated sequence of pchar
- QByteArray result;
- result.reserve(tmp.encodedPath.length());
- if (tmp.encodedPath.startsWith('/'))
- result.append('/');
-
- const char *data = tmp.encodedPath.constData();
- int lastSlash = 0;
- int nextSlash;
- do {
- ++lastSlash;
- nextSlash = tmp.encodedPath.indexOf('/', lastSlash);
- int len;
- if (nextSlash == -1)
- len = tmp.encodedPath.length() - lastSlash;
- else
- len = nextSlash - lastSlash;
-
- if (memchr(data + lastSlash, '%', len)) {
- // there's at least one percent before the next slash
- QByteArray block = QByteArray(data + lastSlash, len);
- q_normalizePercentEncoding(&block, pathExcludeChars);
- result.append(block);
- } else {
- // no percents in this path segment, append wholesale
- result.append(data + lastSlash, len);
- }
-
- // append the slash too, if it's there
- if (nextSlash != -1)
- result.append('/');
-
- lastSlash = nextSlash;
- } while (lastSlash != -1);
-
- tmp.encodedPath = result;
- }
-
- if (!tmp.scheme.isEmpty()) // relative test
- removeDotsFromPath(&tmp.encodedPath);
-
- int qLen = tmp.query.length();
- for (int i = 0; i < qLen; i++) {
- if (qLen - i > 2 && tmp.query.at(i) == '%') {
- ++i;
- tmp.query[i] = qToLower(tmp.query.at(i));
- ++i;
- tmp.query[i] = qToLower(tmp.query.at(i));
- }
- }
- encodedNormalized = tmp.toEncoded();
-
- return encodedNormalized;
-}
#endif
/*!
@@ -1692,7 +1673,9 @@ inline const QByteArray &QUrlPrivate::normalized() const
/*!
Constructs a URL by parsing \a url. QUrl will automatically percent encode
all characters that are not allowed in a URL and decode the percent-encoded
- sequences that represent a character that is allowed in a URL.
+ sequences that represent an unreserved character (letters, digits, hyphens,
+ undercores, dots and tildes). All other characters are left in their
+ original forms.
Parses the \a url using the parser mode \a parsingMode. In TolerantMode
(the default), QUrl will correct certain mistakes, notably the presence of
@@ -1794,8 +1777,9 @@ void QUrl::clear()
/*!
Parses \a url and sets this object to that value. QUrl will automatically
percent encode all characters that are not allowed in a URL and decode the
- percent-encoded sequences that represent a character that is allowed in a
- URL.
+ percent-encoded sequences that represent an unreserved character (letters,
+ digits, hyphens, undercores, dots and tildes). All other characters are
+ left in their original forms.
Parses the \a url using the parser mode \a parsingMode. In TolerantMode
(the default), QUrl will correct certain mistakes, notably the presence of
@@ -1869,6 +1853,7 @@ void QUrl::setScheme(const QString &scheme)
The scheme can only contain US-ASCII letters or digits, which means it
cannot contain any character that would otherwise require encoding.
+ Additionally, schemes are always returned in lowercase form.
\sa setScheme(), isRelative()
*/
@@ -1900,10 +1885,11 @@ QString QUrl::scheme() const
and some characters (including space) are not allowed in undecoded form. In
TolerantMode (the default), all characters are accepted in undecoded form
and the tolerant parser will correct stray '%' not followed by two hex
- characters. In DecodedMode, '%' stand for themselves and encoded characters
- are not possible. Because of that, in DecodedMode, it is not possible to
- use the delimiter characters as non-delimiters (e.g., a password containing
- a '@').
+ characters.
+
+ This function does not allow \a mode to be QUrl::DecodedMode. To set fully
+ decoded data, call setUserName(), setPassword(), setHost() and setPort()
+ individually.
\sa setUserInfo(), setHost(), setPort()
*/
@@ -1911,13 +1897,13 @@ void QUrl::setAuthority(const QString &authority, ParsingMode mode)
{
detach();
d->clearError();
- QString data = authority;
+
if (mode == DecodedMode) {
- parseDecodedComponent(data);
- mode = TolerantMode;
+ qWarning("QUrl::setAuthority(): QUrl::DecodedMode is not permitted in this function");
+ return;
}
- d->setAuthority(data, 0, data.length(), mode);
+ d->setAuthority(authority, 0, authority.length(), mode);
if (authority.isNull()) {
// QUrlPrivate::setAuthority cleared almost everything
// but it leaves the Host bit set
@@ -1929,13 +1915,14 @@ void QUrl::setAuthority(const QString &authority, ParsingMode mode)
Returns the authority of the URL if it is defined; otherwise
an empty string is returned.
- The \a options argument controls how to format the authority portion of the
- URL. The value of QUrl::FullyDecoded should be avoided, since it may
- produce an ambiguous return value (for example, if the username contains a
- colon ':' or either the username or password contain an at-sign '@'). In
- all other cases, this function returns an unambiguous value, which may
- contain those characters still percent-encoded, plus some control
- sequences not representable in decoded form in QString.
+ This function returns an unambiguous value, which may contain that
+ characters still percent-encoded, plus some control sequences not
+ representable in decoded form in QString.
+
+ The \a options argument controls how to format the user info component. The
+ value of QUrl::FullyDecoded is not permitted in this function. If you need
+ to obtain fully decoded data, call userName(), password(), host() and
+ port() individually.
\sa setAuthority(), userInfo(), userName(), password(), host(), port()
*/
@@ -1943,6 +1930,11 @@ QString QUrl::authority(ComponentFormattingOptions options) const
{
if (!d) return QString();
+ if (options == QUrl::FullyDecoded) {
+ qWarning("QUrl::authority(): QUrl::FullyDecoded is not permitted in this function");
+ return QString();
+ }
+
QString result;
d->appendAuthority(result, options, QUrlPrivate::Authority);
return result;
@@ -1964,9 +1956,10 @@ QString QUrl::authority(ComponentFormattingOptions options) const
and some characters (including space) are not allowed in undecoded form. In
TolerantMode (the default), all characters are accepted in undecoded form
and the tolerant parser will correct stray '%' not followed by two hex
- characters. In DecodedMode, '%' stand for themselves and encoded characters
- are not possible. Because of that, in DecodedMode, it is not possible to
- use the ':' delimiter characters as non-delimiter in the user name.
+ characters.
+
+ This function does not allow \a mode to be QUrl::DecodedMode. To set fully
+ decoded data, call setUserName() and setPassword() individually.
\sa userInfo(), setUserName(), setPassword(), setAuthority()
*/
@@ -1976,8 +1969,8 @@ void QUrl::setUserInfo(const QString &userInfo, ParsingMode mode)
d->clearError();
QString trimmed = userInfo.trimmed();
if (mode == DecodedMode) {
- parseDecodedComponent(trimmed);
- mode = TolerantMode;
+ qWarning("QUrl::setUserInfo(): QUrl::DecodedMode is not permitted in this function");
+ return;
}
d->setUserInfo(trimmed, 0, trimmed.length());
@@ -1996,12 +1989,13 @@ void QUrl::setUserInfo(const QString &userInfo, ParsingMode mode)
Returns the user info of the URL, or an empty string if the user
info is undefined.
+ This function returns an unambiguous value, which may contain that
+ characters still percent-encoded, plus some control sequences not
+ representable in decoded form in QString.
+
The \a options argument controls how to format the user info component. The
- value of QUrl::FullyDecoded should be avoided, since it may produce an
- ambiguous return value (for example, if the username contains a colon ':').
- In all other cases, this function returns an unambiguous value, which may
- contain that characters still percent-encoded, plus some control sequences
- not representable in decoded form in QString.
+ value of QUrl::FullyDecoded is not permitted in this function. If you need
+ to obtain fully decoded data, call userName() and password() individually.
\sa setUserInfo(), userName(), password(), authority()
*/
@@ -2009,6 +2003,11 @@ QString QUrl::userInfo(ComponentFormattingOptions options) const
{
if (!d) return QString();
+ if (options == QUrl::FullyDecoded) {
+ qWarning("QUrl::userInfo(): QUrl::FullyDecoded is not permitted in this function");
+ return QString();
+ }
+
QString result;
d->appendUserInfo(result, options, QUrlPrivate::UserInfo);
return result;
@@ -2458,6 +2457,36 @@ QString QUrl::path(ComponentFormattingOptions options) const
*/
/*!
+ \since 5.2
+
+ Returns the name of the file, excluding the directory path.
+
+ Note that, if this QUrl object is given a path ending in a slash, the name of the file is considered empty.
+
+ If the path doesn't contain any slash, it is fully returned as the fileName.
+
+ Example:
+
+ \snippet code/src_corelib_io_qurl.cpp 7
+
+ The \a options argument controls how to format the file name component. All
+ values produce an unambiguous result. With QUrl::FullyDecoded, all
+ percent-encoded sequences are decoded; otherwise, the returned value may
+ contain some percent-encoded sequences for some control sequences not
+ representable in decoded form in QString.
+
+ \sa path()
+*/
+QString QUrl::fileName(ComponentFormattingOptions options) const
+{
+ const QString ourPath = path(options);
+ const int slash = ourPath.lastIndexOf(QLatin1Char('/'));
+ if (slash == -1)
+ return ourPath;
+ return ourPath.mid(slash + 1);
+}
+
+/*!
\since 4.2
Returns true if this URL contains a Query (i.e., if ? was seen on it).
@@ -2903,7 +2932,7 @@ QString QUrl::fragment(ComponentFormattingOptions options) const
if (!d) return QString();
QString result;
- d->appendFragment(result, options);
+ d->appendFragment(result, options, QUrlPrivate::Fragment);
if (d->hasFragment() && result.isNull())
result.detach();
return result;
@@ -2976,7 +3005,7 @@ QString QUrl::topLevelDomain(ComponentFormattingOptions options) const
{
QString tld = qTopLevelDomain(host());
if (options & EncodeUnicode) {
- return qt_ACE_do(tld, ToAceOnly);
+ return qt_ACE_do(tld, ToAceOnly, AllowLeadingDot);
}
return tld;
}
@@ -3148,12 +3177,8 @@ QString QUrl::toString(FormattingOptions options) const
url += QLatin1String("//");
}
- if (!(options & QUrl::RemovePath)) {
+ if (!(options & QUrl::RemovePath))
d->appendPath(url, options, QUrlPrivate::FullUrl);
- // check if we need to remove trailing slashes
- if ((options & StripTrailingSlash) && !d->path.isEmpty() && d->path != QLatin1String("/") && url.endsWith(QLatin1Char('/')))
- url.chop(1);
- }
if (!(options & QUrl::RemoveQuery) && d->hasQuery()) {
url += QLatin1Char('?');
@@ -3161,7 +3186,7 @@ QString QUrl::toString(FormattingOptions options) const
}
if (!(options & QUrl::RemoveFragment) && d->hasFragment()) {
url += QLatin1Char('#');
- d->appendFragment(url, options);
+ d->appendFragment(url, options, QUrlPrivate::FullUrl);
}
return url;
@@ -3188,6 +3213,52 @@ QString QUrl::toDisplayString(FormattingOptions options) const
}
/*!
+ \since 5.2
+
+ Returns an adjusted version of the URL.
+ The output can be customized by passing flags with \a options.
+
+ The encoding options from QUrl::ComponentFormattingOption don't make
+ much sense for this method, nor does QUrl::PreferLocalFile.
+
+ This is always equivalent to QUrl(url.toString(options)).
+
+ \sa FormattingOptions, toEncoded(), toString()
+*/
+QUrl QUrl::adjusted(QUrl::FormattingOptions options) const
+{
+ if (!isValid()) {
+ // also catches isEmpty()
+ return QUrl();
+ }
+ QUrl that = *this;
+ if (options & RemoveScheme)
+ that.setScheme(QString());
+ if ((options & RemoveAuthority) == RemoveAuthority) {
+ that.setAuthority(QString());
+ } else {
+ if ((options & RemoveUserInfo) == RemoveUserInfo)
+ that.setUserInfo(QString());
+ else if (options & RemovePassword)
+ that.setPassword(QString());
+ if (options & RemovePort)
+ that.setPort(-1);
+ }
+ if (options & RemoveQuery)
+ that.setQuery(QString());
+ if (options & RemoveFragment)
+ that.setFragment(QString());
+ if (options & RemovePath) {
+ that.setPath(QString());
+ } else if (options & (StripTrailingSlash | RemoveFilename | NormalizePathSegments)) {
+ QString path;
+ d->appendPath(path, options | FullyEncoded, QUrlPrivate::Path);
+ that.setPath(path, TolerantMode);
+ }
+ return that;
+}
+
+/*!
Returns the encoded representation of the URL if it's valid;
otherwise an empty QByteArray is returned. The output can be
customized by passing flags with \a options.
@@ -3296,7 +3367,7 @@ QString QUrl::fromEncodedComponent_helper(const QByteArray &ba)
*/
QString QUrl::fromAce(const QByteArray &domain)
{
- return qt_ACE_do(QString::fromLatin1(domain), NormalizeAce);
+ return qt_ACE_do(QString::fromLatin1(domain), NormalizeAce, ForbidLeadingDot /*FIXME: make configurable*/);
}
/*!
@@ -3317,7 +3388,7 @@ QString QUrl::fromAce(const QByteArray &domain)
*/
QByteArray QUrl::toAce(const QString &domain)
{
- QString result = qt_ACE_do(domain, ToAceOnly);
+ QString result = qt_ACE_do(domain, ToAceOnly, ForbidLeadingDot /*FIXME: make configurable*/);
return result.toLatin1();
}
@@ -3403,6 +3474,75 @@ bool QUrl::operator ==(const QUrl &url) const
}
/*!
+ \since 5.2
+
+ Returns true if this URL and the given \a url are equal after
+ applying \a options to both; otherwise returns false.
+
+ This is equivalent to calling adjusted(options) on both URLs
+ and comparing the resulting urls, but faster.
+
+*/
+bool QUrl::matches(const QUrl &url, FormattingOptions options) const
+{
+ if (!d && !url.d)
+ return true;
+ if (!d)
+ return url.d->isEmpty();
+ if (!url.d)
+ return d->isEmpty();
+
+ // Compare which sections are present, but ignore Host
+ // which is set by parsing but not by construction, when empty.
+ int mask = QUrlPrivate::FullUrl & ~QUrlPrivate::Host;
+
+ if (options & QUrl::RemoveScheme)
+ mask &= ~QUrlPrivate::Scheme;
+ else if (d->scheme != url.d->scheme)
+ return false;
+
+ if (options & QUrl::RemovePassword)
+ mask &= ~QUrlPrivate::Password;
+ else if (d->password != url.d->password)
+ return false;
+
+ if (options & QUrl::RemoveUserInfo)
+ mask &= ~QUrlPrivate::UserName;
+ else if (d->userName != url.d->userName)
+ return false;
+
+ if (options & QUrl::RemovePort)
+ mask &= ~QUrlPrivate::Port;
+ else if (d->port != url.d->port)
+ return false;
+
+ if (options & QUrl::RemoveAuthority)
+ mask &= ~QUrlPrivate::Host;
+ else if (d->host != url.d->host)
+ return false;
+
+ if (options & QUrl::RemoveQuery)
+ mask &= ~QUrlPrivate::Query;
+ else if (d->query != url.d->query)
+ return false;
+
+ if (options & QUrl::RemoveFragment)
+ mask &= ~QUrlPrivate::Fragment;
+ else if (d->fragment != url.d->fragment)
+ return false;
+
+ if (!(d->sectionIsPresent & mask) == (url.d->sectionIsPresent & mask))
+ return false;
+
+ // Compare paths, after applying path-related options
+ QString path1;
+ d->appendPath(path1, options, QUrlPrivate::Path);
+ QString path2;
+ url.d->appendPath(path2, options, QUrlPrivate::Path);
+ return path1 == path2;
+}
+
+/*!
Returns true if this URL and the given \a url are not equal;
otherwise returns false.
*/
@@ -3668,8 +3808,10 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err
return QString(); // doesn't happen yet
case QUrlPrivate::InvalidIPv6AddressError:
return QStringLiteral("Invalid IPv6 address");
+ case QUrlPrivate::InvalidCharacterInIPv6Error:
+ return QStringLiteral("Invalid IPv6 address (character '%1' not permitted)").arg(c);
case QUrlPrivate::InvalidIPvFutureError:
- return QStringLiteral("Invalid IPvFuture address");
+ return QStringLiteral("Invalid IPvFuture address (character '%1' not permitted)").arg(c);
case QUrlPrivate::HostMissingEndBracket:
return QStringLiteral("Expected ']' to match '[' in hostname");
@@ -3825,9 +3967,9 @@ uint qHash(const QUrl &url, uint seed) Q_DECL_NOTHROW
static QUrl adjustFtpPath(QUrl url)
{
if (url.scheme() == ftpScheme()) {
- QString path = url.path();
+ QString path = url.path(QUrl::PrettyDecoded);
if (path.startsWith(QLatin1String("//")))
- url.setPath(QLatin1String("/%2F") + path.midRef(2));
+ url.setPath(QLatin1String("/%2F") + path.midRef(2), QUrl::TolerantMode);
}
return url;
}
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index cf208bf71e..abb7df0056 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -140,7 +140,9 @@ public:
RemoveFragment = 0x80,
// 0x100 was a private code in Qt 4, keep unused for a while
PreferLocalFile = 0x200,
- StripTrailingSlash = 0x400
+ StripTrailingSlash = 0x400,
+ RemoveFilename = 0x800,
+ NormalizePathSegments = 0x1000
};
enum ComponentFormattingOption {
@@ -185,6 +187,7 @@ public:
QString url(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
QString toString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
QString toDisplayString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
+ QUrl adjusted(FormattingOptions options) const;
QByteArray toEncoded(FormattingOptions options = FullyEncoded) const;
static QUrl fromEncoded(const QByteArray &url, ParsingMode mode = TolerantMode);
@@ -206,21 +209,22 @@ public:
void setUserInfo(const QString &userInfo, ParsingMode mode = TolerantMode);
QString userInfo(ComponentFormattingOptions options = PrettyDecoded) const;
- void setUserName(const QString &userName, ParsingMode mode = TolerantMode);
- QString userName(ComponentFormattingOptions options = PrettyDecoded) const;
+ void setUserName(const QString &userName, ParsingMode mode = DecodedMode);
+ QString userName(ComponentFormattingOptions options = FullyDecoded) const;
- void setPassword(const QString &password, ParsingMode mode = TolerantMode);
- QString password(ComponentFormattingOptions = PrettyDecoded) const;
+ void setPassword(const QString &password, ParsingMode mode = DecodedMode);
+ QString password(ComponentFormattingOptions = FullyDecoded) const;
- void setHost(const QString &host, ParsingMode mode = TolerantMode);
- QString host(ComponentFormattingOptions = PrettyDecoded) const;
- QString topLevelDomain(ComponentFormattingOptions options = PrettyDecoded) const;
+ void setHost(const QString &host, ParsingMode mode = DecodedMode);
+ QString host(ComponentFormattingOptions = FullyDecoded) const;
+ QString topLevelDomain(ComponentFormattingOptions options = FullyDecoded) const;
void setPort(int port);
int port(int defaultPort = -1) const;
- void setPath(const QString &path, ParsingMode mode = TolerantMode);
- QString path(ComponentFormattingOptions options = PrettyDecoded) const;
+ void setPath(const QString &path, ParsingMode mode = DecodedMode);
+ QString path(ComponentFormattingOptions options = FullyDecoded) const;
+ QString fileName(ComponentFormattingOptions options = FullyDecoded) const;
bool hasQuery() const;
void setQuery(const QString &query, ParsingMode mode = TolerantMode);
@@ -247,6 +251,8 @@ public:
bool operator ==(const QUrl &url) const;
bool operator !=(const QUrl &url) const;
+ bool matches(const QUrl &url, FormattingOptions options) const;
+
static QString fromPercentEncoding(const QByteArray &);
static QByteArray toPercentEncoding(const QString &,
const QByteArray &exclude = QByteArray(),
diff --git a/src/corelib/io/qurl_p.h b/src/corelib/io/qurl_p.h
index a0c1882162..9c8fe1cfc6 100644
--- a/src/corelib/io/qurl_p.h
+++ b/src/corelib/io/qurl_p.h
@@ -63,8 +63,9 @@ extern Q_AUTOTEST_EXPORT int qt_urlRecode(QString &appendTo, const QChar *begin,
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications = 0);
// in qurlidna.cpp
+enum AceLeadingDot { AllowLeadingDot, ForbidLeadingDot };
enum AceOperation { ToAceOnly, NormalizeAce };
-extern QString qt_ACE_do(const QString &domain, AceOperation op);
+extern QString qt_ACE_do(const QString &domain, AceOperation op, AceLeadingDot dot);
extern Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from);
extern Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len);
extern Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output);
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index 70db9e09eb..e959faccd2 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -2461,7 +2461,7 @@ static int nextDotDelimiter(const QString &domain, int from = 0)
return ch - b;
}
-QString qt_ACE_do(const QString &domain, AceOperation op)
+QString qt_ACE_do(const QString &domain, AceOperation op, AceLeadingDot dot)
{
if (domain.isEmpty())
return domain;
@@ -2479,7 +2479,8 @@ QString qt_ACE_do(const QString &domain, AceOperation op)
if (labelLength == 0) {
if (idx == domain.length())
break;
- return QString(); // two delimiters in a row -- empty label not allowed
+ if (dot == ForbidLeadingDot || idx > 0)
+ return QString(); // two delimiters in a row -- empty label not allowed
}
// RFC 3490 says, about the ToASCII operation:
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index 547084840f..f6b5cd44bd 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE
All of the getter methods in QUrlQuery support an optional parameter of type
QUrl::ComponentFormattingOptions, including query(), which dictate how to
- encode the data in question. Regardless of the mode, the returned value must
+ encode the data in question. Except for QUrl::FullyDecoded, the returned value must
still be considered a percent-encoded string, as there are certain values
which cannot be expressed in decoded form (like control characters, byte
sequences not decodable to UTF-8). For that reason, the percent character is
@@ -104,6 +104,20 @@ QT_BEGIN_NAMESPACE
"+" sequences found in the keys, values, or query string are left exactly
like written (except for the uppercasing of "%2b" to "%2B").
+ \section2 Full decoding
+
+ With QUrl::FullyDecoded formatting, all percent-encoded sequences will be
+ decoded fully and the '%' character is used to represent itself.
+ QUrl::FullyDecoded should be used with care, since it may cause data loss.
+ See the documentation of QUrl::FullyDecoded for information on what data may
+ be lost.
+
+ This formatting mode should be used only when dealing with text presented to
+ the user in contexts where percent-encoding is not desired. Note that
+ QUrlQuery setters and query methods do not support the counterpart
+ QUrl::DecodedMode parsing, so using QUrl::FullyDecoded to obtain a listing of
+ keys may result in keys not found in the object.
+
\section1 Non-standard delimiters
By default, QUrlQuery uses an equal sign ("=") to separate a key from its
@@ -191,12 +205,9 @@ template<> void QSharedDataPointer<QUrlQueryPrivate>::detach()
// the getter methods, when called with the default encoding value, will not
// have to recode anything (except for toString()).
//
-// The "+" sub-delimiter is always left untouched. We never encode "+" to "%2B"
-// nor do we decode "%2B" to "+", no matter what the user asks.
-//
-// The rest of the delimiters are kept in their decoded forms and that's
-// considered non-ambiguous. That includes the pair and value delimiters
-// themselves.
+// QUrlQuery handling of delimiters is quite simple: we never touch any of
+// them, except for the "#" character and the pair and value delimiters. Those
+// are always kept in their decoded forms.
//
// But when recreating the query string, in toString(), we must take care of
// the special delimiters: the pair and value delimiters, as well as the "#"
@@ -205,12 +216,17 @@ template<> void QSharedDataPointer<QUrlQueryPrivate>::detach()
#define decode(x) ushort(x)
#define leave(x) ushort(0x100 | (x))
#define encode(x) ushort(0x200 | (x))
-static const ushort prettyDecodedActions[] = { leave('+'), 0 };
inline QString QUrlQueryPrivate::recodeFromUser(const QString &input) const
{
// note: duplicated in setQuery()
QString output;
+ ushort prettyDecodedActions[] = {
+ decode(pairDelimiter.unicode()),
+ decode(valueDelimiter.unicode()),
+ decode('#'),
+ 0
+ };
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(),
QUrl::DecodeReserved,
prettyDecodedActions))
@@ -233,7 +249,7 @@ inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::Compon
if (!(encoding & QUrl::EncodeDelimiters)) {
QString output;
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(),
- encoding, prettyDecodedActions))
+ encoding, 0))
return output;
return input;
}
@@ -249,6 +265,13 @@ inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::Compon
void QUrlQueryPrivate::setQuery(const QString &query)
{
+ ushort prettyDecodedActions[] = {
+ decode(pairDelimiter.unicode()),
+ decode(valueDelimiter.unicode()),
+ decode('#'),
+ 0
+ };
+
itemList.clear();
const QChar *pos = query.constData();
const QChar *const end = pos + query.size();
@@ -461,24 +484,18 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const
return QString();
// unlike the component encoding, for the whole query we need to modify a little:
- // - the "#" character is ambiguous, so we decode it only in DecodeAllDelimiters mode
+ // - the "#" character is unambiguous, so we encode it in EncodeDelimiters mode
// - the query delimiter pair must always be encoded
- // - the non-delimiters vary on DecodeUnambiguousDelimiters
- // so:
- // - full encoding: encode the non-delimiters, the pair, "#", "[" and "]"
- // - pretty decode: decode the non-delimiters, "[" and "]"; encode the pair and "#"
- // - decode all: decode the non-delimiters, "[", "]", "#"; encode the pair
// start with what's always encoded
ushort tableActions[] = {
- leave('+'), // 0
- encode(d->pairDelimiter.unicode()), // 1
- encode(d->valueDelimiter.unicode()), // 2
- decode('#'), // 3
+ encode(d->pairDelimiter.unicode()), // 0
+ encode(d->valueDelimiter.unicode()), // 1
+ 0, // 2
0
};
if (encoding & QUrl::EncodeDelimiters) {
- tableActions[3] = encode('#');
+ tableActions[2] = encode('#');
}
QString result;
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index 5ff0c40a4f..7e77b9c251 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -113,59 +113,6 @@ static const uchar defaultActionTable[96] = {
// 0x00 if it belongs to this category
// 0xff if it doesn't
-static const uchar delimsMask[96] = {
- 0xff, // space
- 0x00, // '!' (sub-delim)
- 0xff, // '"'
- 0x00, // '#' (gen-delim)
- 0x00, // '$' (gen-delim)
- 0xff, // '%' (percent)
- 0x00, // '&' (gen-delim)
- 0x00, // "'" (sub-delim)
- 0x00, // '(' (sub-delim)
- 0x00, // ')' (sub-delim)
- 0x00, // '*' (sub-delim)
- 0x00, // '+' (sub-delim)
- 0x00, // ',' (sub-delim)
- 0xff, // '-' (unreserved)
- 0xff, // '.' (unreserved)
- 0x00, // '/' (gen-delim)
-
- 0xff, 0xff, 0xff, 0xff, 0xff, // '0' to '4' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // '5' to '9' (unreserved)
- 0x00, // ':' (gen-delim)
- 0x00, // ';' (sub-delim)
- 0xff, // '<'
- 0x00, // '=' (sub-delim)
- 0xff, // '>'
- 0x00, // '?' (gen-delim)
-
- 0x00, // '@' (gen-delim)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' to 'E' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'F' to 'J' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'K' to 'O' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' to 'T' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'U' to 'Z' (unreserved)
- 0x00, // '[' (gen-delim)
- 0xff, // '\'
- 0x00, // ']' (gen-delim)
- 0xff, // '^'
- 0xff, // '_' (unreserved)
-
- 0xff, // '`'
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' to 'e' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'f' to 'j' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'k' to 'o' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' to 't' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'u' to 'z' (unreserved)
- 0xff, // '{'
- 0xff, // '|'
- 0xff, // '}'
- 0xff, // '~' (unreserved)
-
- 0xff // BSKP
-};
-
static const uchar reservedMask[96] = {
0xff, // space
0xff, // '!' (sub-delim)
@@ -560,6 +507,27 @@ non_trivial:
return 0;
}
+/*!
+ \since 5.0
+ \internal
+
+ This function decodes a percent-encoded string located from \a begin to \a
+ end, by appending each character to \a appendTo. It returns the number of
+ characters appended. Each percent-encoded sequence is decoded as follows:
+
+ \list
+ \li from %00 to %7F: the exact decoded value is appended;
+ \li from %80 to %FF: QChar::ReplacementCharacter is appended;
+ \li bad encoding: original input is copied to the output, undecoded.
+ \endlist
+
+ Given the above, it's important for the input to already have all UTF-8
+ percent sequences decoded by qt_urlRecode (that is, the input should not
+ have been processed with QUrl::EncodeUnicode).
+
+ The input should also be a valid percent-encoded sequence (the output of
+ qt_urlRecode is always valid).
+*/
static int decode(QString &appendTo, const ushort *begin, const ushort *end)
{
const int origSize = appendTo.size();
@@ -573,6 +541,13 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
continue;
}
+ if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) {
+ // badly-encoded data
+ appendTo.resize(origSize + (end - begin));
+ memcpy(appendTo.begin() + origSize, begin, (end - begin) * sizeof(ushort));
+ return end - begin;
+ }
+
if (Q_UNLIKELY(!output)) {
// detach
appendTo.resize(origSize + (end - begin));
@@ -582,10 +557,9 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
}
++input;
- Q_ASSERT(input <= end - 2); // we need two characters
- Q_ASSERT(isHex(input[0]));
- Q_ASSERT(isHex(input[1]));
*output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]);
+ if (output[-1] >= 0x80)
+ output[-1] = QChar::ReplacementCharacter;
input += 2;
}
@@ -613,8 +587,6 @@ static void maskTable(uchar (&table)[N], const uchar (&mask)[N])
The \a encoding option modifies the default behaviour:
\list
- \li QUrl::EncodeDelimiters: if set, delimiters will be left untransformed (note: not encoded!);
- if unset, delimiters will be decoded
\li QUrl::DecodeReserved: if set, reserved characters will be decoded;
if unset, reserved characters will be encoded
\li QUrl::EncodeSpaces: if set, spaces will be encoded to "%20"; if unset, they will be " "
@@ -635,6 +607,9 @@ static void maskTable(uchar (&table)[N], const uchar (&mask)[N])
handled. It consists of a sequence of 16-bit values, where the low 8 bits
indicate the character in question and the high 8 bits are either \c
EncodeCharacter, \c LeaveCharacter or \c DecodeCharacter.
+
+ This function corrects percent-encoded errors by interpreting every '%' as
+ meaning "%25" (all percents in the same content).
*/
Q_AUTOTEST_EXPORT int
@@ -646,24 +621,11 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end));
}
- if (!(encoding & QUrl::EncodeDelimiters) && encoding & QUrl::DecodeReserved) {
- // reset the table
- memset(actionTable, DecodeCharacter, sizeof actionTable);
- if (encoding & QUrl::EncodeSpaces)
- actionTable[0] = EncodeCharacter;
-
- // these are always encoded
- actionTable['%' - ' '] = EncodeCharacter;
- actionTable[0x7F - ' '] = EncodeCharacter;
- } else {
- memcpy(actionTable, defaultActionTable, sizeof actionTable);
- if (!(encoding & QUrl::EncodeDelimiters))
- maskTable(actionTable, delimsMask);
- if (encoding & QUrl::DecodeReserved)
- maskTable(actionTable, reservedMask);
- if (!(encoding & QUrl::EncodeSpaces))
- actionTable[0] = DecodeCharacter; // decode
- }
+ memcpy(actionTable, defaultActionTable, sizeof actionTable);
+ if (encoding & QUrl::DecodeReserved)
+ maskTable(actionTable, reservedMask);
+ if (!(encoding & QUrl::EncodeSpaces))
+ actionTable[0] = DecodeCharacter; // decode
if (tableModifications) {
for (const ushort *p = tableModifications; *p; ++p)
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 4162e843a7..9791a02723 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -160,8 +160,8 @@ QPersistentModelIndex::~QPersistentModelIndex()
}
/*!
- Returns true if this persistent model index is equal to the \a other
- persistent model index; otherwise returns false.
+ Returns \c{true} if this persistent model index is equal to the \a other
+ persistent model index; otherwise returns \c{false}.
All values in the persistent model index are used when comparing
with another persistent model index.
@@ -177,8 +177,8 @@ bool QPersistentModelIndex::operator==(const QPersistentModelIndex &other) const
/*!
\since 4.1
- Returns true if this persistent model index is smaller than the \a other
- persistent model index; otherwise returns false.
+ Returns \c{true} if this persistent model index is smaller than the \a other
+ persistent model index; otherwise returns \c{false}.
All values in the persistent model index are used when comparing
with another persistent model index.
@@ -196,8 +196,8 @@ bool QPersistentModelIndex::operator<(const QPersistentModelIndex &other) const
\fn bool QPersistentModelIndex::operator!=(const QPersistentModelIndex &other) const
\since 4.2
- Returns true if this persistent model index is not equal to the \a
- other persistent model index; otherwise returns false.
+ Returns \c{true} if this persistent model index is not equal to the \a
+ other persistent model index; otherwise returns \c{false}.
*/
/*!
@@ -258,8 +258,8 @@ QPersistentModelIndex::operator const QModelIndex&() const
/*!
\fn bool QPersistentModelIndex::operator==(const QModelIndex &other) const
- Returns true if this persistent model index refers to the same location as
- the \a other model index; otherwise returns false.
+ Returns \c{true} if this persistent model index refers to the same location as
+ the \a other model index; otherwise returns \c{false}.
All values in the persistent model index are used when comparing with
another model index.
@@ -275,8 +275,8 @@ bool QPersistentModelIndex::operator==(const QModelIndex &other) const
/*!
\fn bool QPersistentModelIndex::operator!=(const QModelIndex &other) const
- Returns true if this persistent model index does not refer to the same
- location as the \a other model index; otherwise returns false.
+ Returns \c{true} if this persistent model index does not refer to the same
+ location as the \a other model index; otherwise returns \c{false}.
*/
bool QPersistentModelIndex::operator!=(const QModelIndex &other) const
@@ -423,8 +423,8 @@ const QAbstractItemModel *QPersistentModelIndex::model() const
/*!
\fn bool QPersistentModelIndex::isValid() const
- Returns true if this persistent model index is valid; otherwise returns
- false.
+ Returns \c{true} if this persistent model index is valid; otherwise returns
+ \c{false}.
A valid index belongs to a model, and has non-negative row and column
numbers.
@@ -522,7 +522,7 @@ static uint typeOfVariant(const QVariant &value)
/*!
\internal
- return true if \a value contains a numerical type
+ Return \c{true} if \a value contains a numerical type.
This function is used by our Q{Tree,Widget,Table}WidgetModel classes to sort.
*/
@@ -984,7 +984,7 @@ void QAbstractItemModel::resetInternalData()
/*!
\fn bool QModelIndex::isValid() const
- Returns true if this model index is valid; otherwise returns false.
+ Returns \c{true} if this model index is valid; otherwise returns \c{false}.
A valid index belongs to a model, and has non-negative row and column
numbers.
@@ -1041,8 +1041,8 @@ void QAbstractItemModel::resetInternalData()
/*!
\fn bool QModelIndex::operator==(const QModelIndex &other) const
- Returns true if this model index refers to the same location as the
- \a other model index; otherwise returns false.
+ Returns \c{true} if this model index refers to the same location as the
+ \a other model index; otherwise returns \c{false}.
All values in the model index are used when comparing with another model
index.
@@ -1052,8 +1052,8 @@ void QAbstractItemModel::resetInternalData()
/*!
\fn bool QModelIndex::operator!=(const QModelIndex &other) const
- Returns true if this model index does not refer to the same location as
- the \a other model index; otherwise returns false.
+ Returns \c{true} if this model index does not refer to the same location as
+ the \a other model index; otherwise returns \c{false}.
*/
@@ -1113,7 +1113,7 @@ void QAbstractItemModel::resetInternalData()
Items can be queried with flags() (see \l Qt::ItemFlag) to see if they can
be selected, dragged, or manipulated in other ways.
- If an item has child objects, hasChildren() returns true for the
+ If an item has child objects, hasChildren() returns \c{true} for the
corresponding index.
The model has a rowCount() and a columnCount() for each level of the
@@ -1236,7 +1236,7 @@ void QAbstractItemModel::resetInternalData()
Inserts a single column before the given \a column in the child items of
the \a parent specified.
- Returns true if the column is inserted; otherwise returns false.
+ Returns \c{true} if the column is inserted; otherwise returns \c{false}.
\sa insertColumns(), insertRow(), removeColumn()
*/
@@ -1249,7 +1249,7 @@ void QAbstractItemModel::resetInternalData()
\note This function calls the virtual method insertRows.
- Returns true if the row is inserted; otherwise returns false.
+ Returns \c{true} if the row is inserted; otherwise returns \c{false}.
\sa insertRows(), insertColumn(), removeRow()
*/
@@ -1284,7 +1284,7 @@ void QAbstractItemModel::resetInternalData()
Removes the given \a column from the child items of the \a parent
specified.
- Returns true if the column is removed; otherwise returns false.
+ Returns \c{true} if the column is removed; otherwise returns \c{false}.
\sa removeColumns(), removeRow(), insertColumn()
*/
@@ -1294,7 +1294,7 @@ void QAbstractItemModel::resetInternalData()
Removes the given \a row from the child items of the \a parent specified.
- Returns true if the row is removed; otherwise returns false.
+ Returns \c{true} if the row is removed; otherwise returns \c{false}.
This is a convenience function that calls removeRows(). The
QAbstractItemModel implementation of removeRows() does nothing.
@@ -1308,8 +1308,8 @@ void QAbstractItemModel::resetInternalData()
On models that support this, moves \a sourceColumn from \a sourceParent to \a destinationChild under
\a destinationParent.
- Returns true if the columns were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully moved; otherwise returns
+ \c{false}.
\sa moveRows(), moveColumn()
*/
@@ -1320,8 +1320,8 @@ void QAbstractItemModel::resetInternalData()
On models that support this, moves \a sourceColumn from \a sourceParent to \a destinationChild under
\a destinationParent.
- Returns true if the columns were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully moved; otherwise returns
+ \c{false}.
\sa moveColumns(), moveRow()
*/
@@ -1663,8 +1663,8 @@ QAbstractItemModel::~QAbstractItemModel()
*/
/*!
- Returns true if the model returns a valid QModelIndex for \a row and
- \a column with \a parent, otherwise returns false.
+ Returns \c{true} if the model returns a valid QModelIndex for \a row and
+ \a column with \a parent, otherwise returns \c{false}.
*/
bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const
{
@@ -1675,7 +1675,7 @@ bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent
/*!
- Returns true if \a parent has any children; otherwise returns false.
+ Returns \c{true} if \a parent has any children; otherwise returns \c{false}.
Use rowCount() on the parent to find out the number of children.
@@ -1732,12 +1732,12 @@ QMap<int, QVariant> QAbstractItemModel::itemData(const QModelIndex &index) const
/*!
Sets the \a role data for the item at \a index to \a value.
- Returns true if successful; otherwise returns false.
+ Returns \c{true} if successful; otherwise returns \c{false}.
The dataChanged() signal should be emitted if the data was successfully
set.
- The base class implementation returns false. This function and data() must
+ The base class implementation returns \c{false}. This function and data() must
be reimplemented for editable models.
\sa Qt::ItemDataRole, data(), itemData()
@@ -1766,7 +1766,7 @@ bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value
Sets the role data for the item at \a index to the associated value in
\a roles, for every Qt::ItemDataRole.
- Returns true if successful; otherwise returns false.
+ Returns \c{true} if successful; otherwise returns \c{false}.
Roles that are not in \a roles will not be modified.
@@ -1781,10 +1781,19 @@ bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, Q
}
/*!
- Returns a list of MIME types that can be used to describe a list of model
- indexes.
+ Returns the list of allowed MIME types. By default, the built-in
+ models and views use an internal MIME type:
+ \c{application/x-qabstractitemmodeldatalist}.
- \sa mimeData()
+ When implementing drag and drop support in a custom model, if you
+ will return data in formats other than the default internal MIME
+ type, reimplement this function to return your list of MIME types.
+
+ If you reimplement this function in your custom model, you must
+ also reimplement the member functions that call it: mimeData() and
+ dropMimeData().
+
+ \sa mimeData(), dropMimeData()
*/
QStringList QAbstractItemModel::mimeTypes() const
{
@@ -1795,11 +1804,14 @@ QStringList QAbstractItemModel::mimeTypes() const
/*!
Returns an object that contains serialized items of data corresponding to
- the list of \a indexes specified. The formats used to describe the encoded
- data is obtained from the mimeTypes() function.
+ the list of \a indexes specified. The format used to describe the encoded
+ data is obtained from the mimeTypes() function. This default implementation
+ uses the default MIME type returned by the default implementation of
+ mimeTypes(). If you reimplement mimeTypes() in your custom model to return
+ more MIME types, reimplement this function to make use of them.
- If the list of indexes is empty, or there are no supported MIME types, 0 is
- returned rather than a serialized empty list.
+ If the list of \a indexes is empty, or there are no supported MIME types, 0
+ is returned rather than a serialized empty list.
\sa mimeTypes(), dropMimeData()
*/
@@ -1820,13 +1832,13 @@ QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
}
/*!
- Returns whether a model can accept a drop of data.
+ Returns \c{true} if a model can accept a drop of the \a data. This
+ default implementation always returns \c{true}.
- This can be used to indicate whether a drop of certain data is allowed, for example
- by using a 'forbidden' emblem on a mouse cursor during a drag operation.
-
- This method returns true by default. Reimplementations can return whether the
- \a data can be dropped at \a row, \a column, \a parent with \a action.
+ Reimplement this function in your custom model, if you want to
+ test whether the \a data can be dropped at \a row, \a column,
+ \a parent with \a action. If you don't need that test, it is not
+ necessary to reimplement this function.
\sa dropMimeData(), {Using drag and drop with item views}
*/
@@ -1846,8 +1858,8 @@ bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction a
Handles the \a data supplied by a drag and drop operation that ended with
the given \a action.
- Returns true if the data and action can be handled by the model; otherwise
- returns false.
+ Returns \c{true} if the data and action were handled by the model; otherwise
+ returns \c{false}.
The specified \a row, \a column and \a parent indicate the location of an
item in the model where the operation ended. It is the responsibility of
@@ -1859,10 +1871,16 @@ bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction a
When \a row and \a column are -1 it means that the dropped data should be
considered as dropped directly on \a parent. Usually this will mean
- appending the data as child items of \a parent. If \a row and column are
+ appending the data as child items of \a parent. If \a row and \a column are
greater than or equal zero, it means that the drop occurred just before the
specified \a row and \a column in the specified \a parent.
+ The mimeTypes() member is called to get the list of acceptable MIME types.
+ This default implementation assumes the default implementation of mimeTypes(),
+ which returns a single default MIME type. If you reimplement mimeTypes() in
+ your custom model to return multiple MIME types, you must reimplement this
+ function to make use of them.
+
\sa supportedDropActions(), canDropMimeData(), {Using drag and drop with item views}
*/
bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
@@ -1950,7 +1968,7 @@ void QAbstractItemModel::doSetSupportedDragActions(Qt::DropActions actions)
/*!
\note The base class implementation of this function does nothing and
- returns false.
+ returns \c{false}.
On models that support this, inserts \a count rows into the model before
the given \a row. Items in the new row will be children of the item
@@ -1964,8 +1982,8 @@ void QAbstractItemModel::doSetSupportedDragActions(Qt::DropActions actions)
If \a parent has no children, a single column with \a count rows is
inserted.
- Returns true if the rows were successfully inserted; otherwise returns
- false.
+ Returns \c{true} if the rows were successfully inserted; otherwise returns
+ \c{false}.
If you implement your own model, you can reimplement this function if you
want to support insertions. Alternatively, you can provide your own API for
@@ -1993,10 +2011,10 @@ bool QAbstractItemModel::insertRows(int, int, const QModelIndex &)
If \a parent has no children, a single row with \a count columns is
inserted.
- Returns true if the columns were successfully inserted; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully inserted; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support insertions. Alternatively, you can provide your own API for
@@ -2013,10 +2031,10 @@ bool QAbstractItemModel::insertColumns(int, int, const QModelIndex &)
On models that support this, removes \a count rows starting with the given
\a row under parent \a parent from the model.
- Returns true if the rows were successfully removed; otherwise returns
- false.
+ Returns \c{true} if the rows were successfully removed; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support removing. Alternatively, you can provide your own API for
@@ -2034,10 +2052,10 @@ bool QAbstractItemModel::removeRows(int, int, const QModelIndex &)
On models that support this, removes \a count columns starting with the
given \a column under parent \a parent from the model.
- Returns true if the columns were successfully removed; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully removed; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support removing. Alternatively, you can provide your own API for
@@ -2056,10 +2074,10 @@ bool QAbstractItemModel::removeColumns(int, int, const QModelIndex &)
\a sourceRow under parent \a sourceParent to row \a destinationChild under
parent \a destinationParent.
- Returns true if the rows were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the rows were successfully moved; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support moving. Alternatively, you can provide your own API for
@@ -2077,10 +2095,10 @@ bool QAbstractItemModel::moveRows(const QModelIndex &, int , int , const QModelI
\a sourceColumn under parent \a sourceParent to column \a destinationChild under
parent \a destinationParent.
- Returns true if the columns were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully moved; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support moving. Alternatively, you can provide your own API for
@@ -2109,10 +2127,10 @@ void QAbstractItemModel::fetchMore(const QModelIndex &)
}
/*!
- Returns true if there is more data available for \a parent; otherwise
- returns false.
+ Returns \c{true} if there is more data available for \a parent; otherwise
+ returns \c{false}.
- The default implementation always returns false.
+ The default implementation always returns \c{false}.
If canFetchMore() returns true, the fetchMore() function should
be called. This is the behavior of QAbstractItemView, for example.
@@ -2310,7 +2328,7 @@ QHash<int,QByteArray> QAbstractItemModel::roleNames() const
Lets the model know that it should submit cached information to permanent
storage. This function is typically used for row editing.
- Returns true if there is no error; otherwise returns false.
+ Returns \c{true} if there is no error; otherwise returns \c{false}.
\sa revert()
*/
@@ -2355,7 +2373,7 @@ QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation
Sets the data for the given \a role and \a section in the header with the
specified \a orientation to the \a value supplied.
- Returns true if the header's data was updated; otherwise returns false.
+ Returns \c{true} if the header's data was updated; otherwise returns \c{false}.
When reimplementing this function, the headerDataChanged() signal must be
emitted explicitly.
@@ -2682,7 +2700,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
you must ensure that the \a destinationChild is not within the range
of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
do not attempt to move a row to one of its own children or ancestors.
- This method returns false if either condition is true, in which case you
+ This method returns \c{false} if either condition is true, in which case you
should abort your move operation.
\table 80%
@@ -2949,7 +2967,7 @@ void QAbstractItemModel::endRemoveColumns()
you must ensure that the \a destinationChild is not within the range
of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
do not attempt to move a column to one of its own children or ancestors.
- This method returns false if either condition is true, in which case you
+ This method returns \c{false} if either condition is true, in which case you
should abort your move operation.
\sa endMoveColumns()
@@ -3596,8 +3614,8 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
\fn bool QModelIndex::operator<(const QModelIndex &other) const
\since 4.1
- Returns true if this model index is smaller than the \a other
- model index; otherwise returns false.
+ Returns \c{true} if this model index is smaller than the \a other
+ model index; otherwise returns \c{false}.
The less than calculation is not directly useful to developers - the way that indexes
with different parents compare is not defined. This operator only exists so that the
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index f3bf2c1019..95b9d271f3 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -113,6 +113,11 @@ public:
inline bool operator!=(const QPersistentModelIndex &other) const
{ return !operator==(other); }
QPersistentModelIndex &operator=(const QPersistentModelIndex &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QPersistentModelIndex(QPersistentModelIndex &&other) : d(other.d) { other.d = 0; }
+ inline QPersistentModelIndex &operator=(QPersistentModelIndex &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline void swap(QPersistentModelIndex &other) { qSwap(d, other.d); }
bool operator==(const QModelIndex &other) const;
bool operator!=(const QModelIndex &other) const;
@@ -427,6 +432,15 @@ public:
int row, int column, const QModelIndex &parent);
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ inline QObject *parent() const { return QAbstractItemModel::parent(); }
+#endif
+#else
+ using QObject::parent;
+#endif
+
protected:
QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent);
@@ -449,6 +463,15 @@ public:
int row, int column, const QModelIndex &parent);
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ inline QObject *parent() const { return QAbstractItemModel::parent(); }
+#endif
+#else
+ using QObject::parent;
+#endif
+
protected:
QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent);
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index 06885ad972..7d0162938d 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -60,8 +60,10 @@
#include <qatomic.h>
#include <qstring.h>
#include <qendian.h>
+#include <qnumeric.h>
#include <limits.h>
+#include <limits>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 9dd9a9cab9..d0634602f3 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -158,6 +158,18 @@ QJsonValue::QJsonValue(int n)
}
/*!
+ \overload
+ Creates a value of type Double, with value \a n.
+ NOTE: the integer limits for IEEE 754 double precision data is 2^53 (-9007199254740992 to +9007199254740992).
+ If you pass in values outside this range expect a loss of precision to occur.
+ */
+QJsonValue::QJsonValue(qint64 n)
+ : d(0), t(Double)
+{
+ this->dbl = n;
+}
+
+/*!
Creates a value of type String, with value \a s.
*/
QJsonValue::QJsonValue(const QString &s)
@@ -439,6 +451,19 @@ bool QJsonValue::toBool(bool defaultValue) const
}
/*!
+ Converts the value to an int and returns it.
+
+ If type() is not Double or the value is not a whole number,
+ the \a defaultValue will be returned.
+ */
+int QJsonValue::toInt(int defaultValue) const
+{
+ if (t == Double && int(dbl) == dbl)
+ return dbl;
+ return defaultValue;
+}
+
+/*!
Converts the value to a double and returns it.
If type() is not Double, the \a defaultValue will be returned.
diff --git a/src/corelib/json/qjsonvalue.h b/src/corelib/json/qjsonvalue.h
index b8bdf55aa3..b18bbde0f7 100644
--- a/src/corelib/json/qjsonvalue.h
+++ b/src/corelib/json/qjsonvalue.h
@@ -79,6 +79,7 @@ public:
QJsonValue(bool b);
QJsonValue(double n);
QJsonValue(int n);
+ QJsonValue(qint64 n);
QJsonValue(const QString &s);
QJsonValue(QLatin1String s);
QJsonValue(const QJsonArray &a);
@@ -102,6 +103,7 @@ public:
inline bool isUndefined() const { return type() == Undefined; }
bool toBool(bool defaultValue = false) const;
+ int toInt(int defaultValue = 0) const;
double toDouble(double defaultValue = 0) const;
QString toString(const QString &defaultValue = QString()) const;
QJsonArray toArray() const;
@@ -157,6 +159,7 @@ public:
inline bool isUndefined() const { return type() == QJsonValue::Undefined; }
inline bool toBool() const { return toValue().toBool(); }
+ inline int toInt() const { return toValue().toInt(); }
inline double toDouble() const { return toValue().toDouble(); }
inline QString toString() const { return toValue().toString(); }
QJsonArray toArray() const;
diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp
index 3ac16c6fd1..8426b351f6 100644
--- a/src/corelib/json/qjsonwriter.cpp
+++ b/src/corelib/json/qjsonwriter.cpp
@@ -169,9 +169,14 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &
case QJsonValue::Bool:
json += v.toBoolean() ? "true" : "false";
break;
- case QJsonValue::Double:
- json += QByteArray::number(v.toDouble(b), 'g', 17);
+ case QJsonValue::Double: {
+ const double d = v.toDouble(b);
+ if (qIsFinite(d)) // +2 to format to ensure the expected precision
+ json += QByteArray::number(d, 'g', std::numeric_limits<double>::digits10 + 2); // ::digits10 is 15
+ else
+ json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
break;
+ }
case QJsonValue::String:
json += '"';
json += escapedString(v.toString(b));
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index f0899c6dee..fa911fb967 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -75,6 +75,12 @@
#include "qstring.h"
+#if defined( __OBJC__) && defined(QT_NAMESPACE)
+#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) @compatibility_alias __KLASS__ QT_MANGLE_NAMESPACE(__KLASS__)
+#else
+#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
+#endif
+
QT_BEGIN_NAMESPACE
/*
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index a7b14b22b5..bba878d2eb 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -589,6 +589,8 @@ void QCoreApplicationPrivate::initLocale()
Note that some arguments supplied by the user may have been
processed and removed by QCoreApplication.
+ For more advanced command line option handling, create a QCommandLineParser.
+
\section1 Locale Settings
On Unix/Linux Qt is configured to use the system locale settings by
@@ -1950,7 +1952,6 @@ QString QCoreApplication::applicationFilePath()
char buff[maximum_path+1];
if (_cmdname(buff)) {
d->cachedApplicationFilePath = QDir::cleanPath(QString::fromLocal8Bit(buff));
- return d->cachedApplicationFilePath;
} else {
qWarning("QCoreApplication::applicationFilePath: _cmdname() failed");
// _cmdname() won't fail, but just in case, fallback to the old method
@@ -1959,11 +1960,11 @@ QString QCoreApplication::applicationFilePath()
if (!executables.empty()) {
//We assume that there is only one executable in the folder
d->cachedApplicationFilePath = dir.absoluteFilePath(executables.first());
- return d->cachedApplicationFilePath;
} else {
- return QString();
+ d->cachedApplicationFilePath = QString();
}
}
+ return d->cachedApplicationFilePath;
#elif defined(Q_OS_MAC)
QString qAppFileName_str = qAppFileName();
if(!qAppFileName_str.isEmpty()) {
@@ -1982,34 +1983,38 @@ QString QCoreApplication::applicationFilePath()
return d->cachedApplicationFilePath;
}
# endif
+ if (!arguments().isEmpty()) {
+ QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
+ QString absPath;
+
+ if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
+ /*
+ If argv0 starts with a slash, it is already an absolute
+ file path.
+ */
+ absPath = argv0;
+ } else if (argv0.contains(QLatin1Char('/'))) {
+ /*
+ If argv0 contains one or more slashes, it is a file path
+ relative to the current directory.
+ */
+ absPath = QDir::current().absoluteFilePath(argv0);
+ } else {
+ /*
+ Otherwise, the file path has to be determined using the
+ PATH environment variable.
+ */
+ absPath = QStandardPaths::findExecutable(argv0);
+ }
+
+ absPath = QDir::cleanPath(absPath);
- QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
- QString absPath;
-
- if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
- /*
- If argv0 starts with a slash, it is already an absolute
- file path.
- */
- absPath = argv0;
- } else if (argv0.contains(QLatin1Char('/'))) {
- /*
- If argv0 contains one or more slashes, it is a file path
- relative to the current directory.
- */
- absPath = QDir::current().absoluteFilePath(argv0);
+ QFileInfo fi(absPath);
+ d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
} else {
- /*
- Otherwise, the file path has to be determined using the
- PATH environment variable.
- */
- absPath = QStandardPaths::findExecutable(argv0);
+ d->cachedApplicationFilePath = QString();
}
- absPath = QDir::cleanPath(absPath);
-
- QFileInfo fi(absPath);
- d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
return d->cachedApplicationFilePath;
#endif
}
@@ -2057,7 +2062,7 @@ qint64 QCoreApplication::applicationPid()
As a result of this, the string given by arguments().at(0) might not be
the program name on Windows, depending on how the application was started.
- \sa applicationFilePath()
+ \sa applicationFilePath(), QCommandLineParser
*/
QStringList QCoreApplication::arguments()
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
index f90f2e3268..d9e38b68b2 100644
--- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp
+++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
@@ -128,16 +128,16 @@ static int bpsIOHandler(int fd, int io_events, void *data)
// create unblock event
bps_event_t *event;
int result = bps_event_create(&event, bpsUnblockDomain, 0, NULL, NULL);
- if (result != BPS_SUCCESS) {
- qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_event_create() failed");
+ if (Q_UNLIKELY(result != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_event_create failed");
return BPS_FAILURE;
}
// post unblock event to our thread; in this callback the bps channel is
// guaranteed to be the same that was active when bps_add_fd was called
result = bps_push_event(event);
- if (result != BPS_SUCCESS) {
- qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_push_event() failed");
+ if (Q_UNLIKELY(result != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_push_event failed");
bps_event_destroy(event);
return BPS_FAILURE;
}
@@ -151,16 +151,16 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
{
// prepare to use BPS
int result = bps_initialize();
- if (result != BPS_SUCCESS)
- qFatal("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_initialize() failed");
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qFatal("QEventDispatcherBlackberry: bps_initialize failed");
bps_channel = bps_channel_get_active();
// get domain for IO ready and wake up events - ignoring race condition here for now
if (bpsUnblockDomain == -1) {
bpsUnblockDomain = bps_register_domain();
- if (bpsUnblockDomain == -1)
- qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_register_domain() failed");
+ if (Q_UNLIKELY(bpsUnblockDomain == -1))
+ qWarning("QEventDispatcherBlackberry: bps_register_domain failed");
}
}
@@ -202,21 +202,26 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie
Q_ASSERT(notifier);
Q_D(QEventDispatcherBlackberry);
- BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
-
- // Register the fd with bps
int sockfd = notifier->socket();
int type = notifier->type();
- qEventDispatcherDebug << Q_FUNC_INFO << "fd =" << sockfd;
- int io_events = ioEvents(sockfd);
+ qEventDispatcherDebug << Q_FUNC_INFO << "fd =" << sockfd;
- if (io_events)
- bps_remove_fd(sockfd);
+ if (Q_UNLIKELY(sockfd >= FD_SETSIZE)) {
+ qWarning() << "QEventDispatcherBlackberry: cannot register QSocketNotifier (fd too high)"
+ << sockfd;
+ return;
+ }
// Call the base Unix implementation. Needed to allow select() to be called correctly
QEventDispatcherUNIX::registerSocketNotifier(notifier);
+ // Register the fd with bps
+ BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
+ int io_events = ioEvents(sockfd);
+ if (io_events)
+ bps_remove_fd(sockfd);
+
switch (type) {
case QSocketNotifier::Read:
qEventDispatcherDebug << "Registering" << sockfd << "for Reads";
@@ -233,44 +238,41 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie
break;
}
- errno = 0;
- int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
-
- if (result != BPS_SUCCESS)
- qWarning() << Q_FUNC_INFO << "bps_add_fd() failed" << strerror(errno) << "code:" << errno;
+ const int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qWarning() << "QEventDispatcherBlackberry: bps_add_fd failed";
}
void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier)
{
Q_D(QEventDispatcherBlackberry);
- BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
+ int sockfd = notifier->socket();
+
+ qEventDispatcherDebug << Q_FUNC_INFO << "fd =" << sockfd;
+
+ if (Q_UNLIKELY(sockfd >= FD_SETSIZE)) {
+ qWarning() << "QEventDispatcherBlackberry: cannot unregister QSocketNotifier" << sockfd;
+ return;
+ }
// Allow the base Unix implementation to unregister the fd too
QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
// Unregister the fd with bps
- int sockfd = notifier->socket();
- qEventDispatcherDebug << Q_FUNC_INFO << "fd =" << sockfd;
-
+ BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
const int io_events = ioEvents(sockfd);
-
int result = bps_remove_fd(sockfd);
- if (result != BPS_SUCCESS)
- qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed" << sockfd;
-
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qWarning() << "QEventDispatcherBlackberry: bps_remove_fd failed" << sockfd;
- /* if no other socket notifier is
- * watching sockfd, our job ends here
- */
+ // if no other socket notifier is watching sockfd, our job ends here
if (!io_events)
return;
- errno = 0;
result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
- if (result != BPS_SUCCESS) {
- qWarning() << Q_FUNC_INFO << "bps_add_fd() failed" << strerror(errno) << "code:" << errno;
- }
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qWarning("QEventDispatcherBlackberry: bps_add_fd error");
}
static inline int timespecToMillisecs(const timespec &tv)
@@ -358,8 +360,8 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
// Wait for event or file to be ready
const int result = bps_get_event(&event, timeoutLeft);
- if (result != BPS_SUCCESS)
- qWarning("QEventDispatcherBlackberry::select: bps_get_event() failed");
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qWarning("QEventDispatcherBlackberry: bps_get_event failed");
}
if (!event) // In case of !event, we break out of the loop to let Qt process the timers
@@ -392,13 +394,13 @@ void QEventDispatcherBlackberry::wakeUp()
Q_D(QEventDispatcherBlackberry);
if (d->wakeUps.testAndSetAcquire(0, 1)) {
bps_event_t *event;
- if (bps_event_create(&event, bpsUnblockDomain, 0, 0, 0) == BPS_SUCCESS) {
- if (bps_channel_push_event(d->bps_channel, event) == BPS_SUCCESS)
+ if (Q_LIKELY(bps_event_create(&event, bpsUnblockDomain, 0, 0, 0) == BPS_SUCCESS)) {
+ if (Q_LIKELY(bps_channel_push_event(d->bps_channel, event) == BPS_SUCCESS))
return;
else
bps_event_destroy(event);
}
- qWarning("QEventDispatcherBlackberryPrivate::wakeUp failed");
+ qWarning("QEventDispatcherBlackberry: wakeUp failed");
}
}
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index 96450f9441..4c727f9d3d 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -90,7 +90,7 @@ Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type)
} // namespace QtPrivate
// copied from qmetaobject.cpp
-static inline const QMetaObjectPrivate *priv(const uint* data)
+static inline Q_DECL_UNUSED const QMetaObjectPrivate *priv(const uint* data)
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
class QMetaMethodBuilderPrivate
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 50f3a1814b..17fbbda720 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -421,6 +421,56 @@ public:
int alias;
};
+template<typename T, typename Key>
+class QMetaTypeFunctionRegistry
+{
+public:
+ ~QMetaTypeFunctionRegistry()
+ {
+ const QWriteLocker locker(&lock);
+ map.clear();
+ }
+
+ bool contains(Key k) const
+ {
+ const QReadLocker locker(&lock);
+ return map.contains(k);
+ }
+
+ bool insertIfNotContains(Key k, const T *f)
+ {
+ const QWriteLocker locker(&lock);
+ const T* &fun = map[k];
+ if (fun != 0)
+ return false;
+ fun = f;
+ return true;
+ }
+
+ const T *function(Key k) const
+ {
+ const QReadLocker locker(&lock);
+ return map.value(k, 0);
+ }
+
+ void remove(int from, int to)
+ {
+ const Key k(from, to);
+ const QWriteLocker locker(&lock);
+ map.remove(k);
+ }
+private:
+ mutable QReadWriteLock lock;
+ QHash<Key, const T *> map;
+};
+
+typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractConverterFunction,QPair<int,int> >
+QMetaTypeConverterRegistry;
+typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractComparatorFunction,int>
+QMetaTypeComparatorRegistry;
+typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
+QMetaTypeDebugStreamRegistry;
+
namespace
{
union CheckThatItIsPod
@@ -432,6 +482,200 @@ union CheckThatItIsPod
Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
+Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
+Q_GLOBAL_STATIC(QMetaTypeComparatorRegistry, customTypesComparatorRegistry)
+Q_GLOBAL_STATIC(QMetaTypeDebugStreamRegistry, customTypesDebugStreamRegistry)
+
+/*!
+ \fn bool QMetaType::registerConverter()
+ \since 5.2
+ Registers the possibility of an implicit conversion from type From to type To in the meta
+ type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(MemberFunction function)
+ \since 5.2
+ \overload
+ Registers a method \a function like To From::function() const as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(MemberFunctionOk function)
+ \since 5.2
+ \overload
+ Registers a method \a function like To From::function(bool *ok) const as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(UnaryFunction function)
+ \since 5.2
+ \overload
+ Registers a unary function object \a function as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerComparators()
+ \since 5.2
+ Registers comparison operetarors for the user-registered type T. This requires T to have
+ both an operator== and an operator<.
+ Returns true if the registration succeeded, otherwise false.
+*/
+
+#ifndef QT_NO_DEBUG_STREAM
+/*!
+ \fn bool QMetaType::registerDebugStreamOperator()
+ Registers the debug stream operator for the user-registered type T. This requires T to have
+ an operator<<(QDebug dbg, T).
+ Returns true if the registration succeeded, otherwise false.
+*/
+#endif
+
+/*!
+ Registers function \a f as converter function from type id \a from to \a to.
+ If there's already a conversion registered, this does nothing but deleting \a f.
+ Returns true if the registration succeeded, otherwise false.
+ \since 5.2
+ \internal
+*/
+bool QMetaType::registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to)
+{
+ if (!customTypesConversionRegistry()->insertIfNotContains(qMakePair(from, to), f)) {
+ qWarning("Type conversion already registered from type %s to type %s",
+ QMetaType::typeName(from), QMetaType::typeName(to));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Invoked automatically when a converter function object is destroyed.
+ */
+void QMetaType::unregisterConverterFunction(int from, int to)
+{
+ if (customTypesConversionRegistry.isDestroyed())
+ return;
+ customTypesConversionRegistry()->remove(from, to);
+}
+
+bool QMetaType::registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type)
+{
+ if (!customTypesComparatorRegistry()->insertIfNotContains(type, f)) {
+ qWarning("Comparators already registered for type %s", QMetaType::typeName(type));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \fn bool QMetaType::hasRegisteredComparators()
+ Returns true, if the meta type system has registered comparators for type T.
+ \since 5.2
+ */
+
+/*!
+ Returns true, if the meta type system has registered comparators for type id \a typeId.
+ \since 5.2
+ */
+bool QMetaType::hasRegisteredComparators(int typeId)
+{
+ return customTypesComparatorRegistry()->contains(typeId);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+bool QMetaType::registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f,
+ int type)
+{
+ if (!customTypesDebugStreamRegistry()->insertIfNotContains(type, f)) {
+ qWarning("Debug stream operator already registered for type %s", QMetaType::typeName(type));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \fn bool QMetaType::hasRegisteredDebugStreamOperator()
+ Returns true, if the meta type system has a registered debug stream operator for type T.
+ \since 5.2
+ */
+
+/*!
+ Returns true, if the meta type system has a registered debug stream operator for type
+ id \a typeId.
+ \since 5.2
+*/
+bool QMetaType::hasRegisteredDebugStreamOperator(int typeId)
+{
+ return customTypesDebugStreamRegistry()->contains(typeId);
+}
+#endif
+
+/*!
+ Converts the object at \a from from \a fromTypeId to the preallocated space at \a to
+ typed \a toTypeId. Returns true, if the conversion succeeded, otherwise false.
+ \since 5.2
+*/
+bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId)
+{
+ const QtPrivate::AbstractConverterFunction * const f =
+ customTypesConversionRegistry()->function(qMakePair(fromTypeId, toTypeId));
+ return f && f->convert(f, from, to);
+}
+
+/*!
+ Compares the objects at \a lhs and \a rhs. Both objects need to be of type \a typeId.
+ \a result is set to less than, equal to or greater than zero, if \a lhs is less than, equal to
+ or greater than \a rhs. Returns true, if the comparison succeeded, otherwiess false.
+ \since 5.2
+*/
+bool QMetaType::compare(const void *lhs, const void *rhs, int typeId, int* result)
+{
+ const QtPrivate::AbstractComparatorFunction * const f =
+ customTypesComparatorRegistry()->function(typeId);
+ if (!f)
+ return false;
+ if (f->equals(f, lhs, rhs))
+ *result = 0;
+ else
+ *result = f->lessThan(f, lhs, rhs) ? -1 : 1;
+ return true;
+}
+
+/*!
+ Streams the object at \a rhs of type \a typeId to the debug stream \a dbg. Returns true
+ on success, otherwise false.
+ \since 5.2
+*/
+bool QMetaType::debugStream(QDebug& dbg, const void *rhs, int typeId)
+{
+ const QtPrivate::AbstractDebugStreamFunction * const f = customTypesDebugStreamRegistry()->function(typeId);
+ if (!f)
+ return false;
+ f->stream(f, dbg, rhs);
+ return true;
+}
+
+/*!
+ \fn bool QMetaType::hasRegisteredConverterFunction()
+ Returns true, if the meta type system has a registered conversion from type From to type To.
+ \since 5.2
+ \overload
+ */
+
+/*!
+ Returns true, if the meta type system has a registered conversion from meta type id \a fromTypeId
+ to \a toTypeId
+ \since 5.2
+*/
+bool QMetaType::hasRegisteredConverterFunction(int fromTypeId, int toTypeId)
+{
+ return customTypesConversionRegistry()->contains(qMakePair(fromTypeId, toTypeId));
+}
#ifndef QT_NO_DATASTREAM
/*!
@@ -723,11 +967,11 @@ int QMetaType::registerNormalizedTypedef(const NS(QByteArray) &normalizedTypeNam
}
if (idx != aliasId) {
- qFatal("QMetaType::registerTypedef: Binary compatibility break "
- "-- Type name '%s' previously registered as typedef of '%s' [%i], "
- "now registering as typedef of '%s' [%i].",
- normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
- QMetaType::typeName(aliasId), aliasId);
+ qWarning("QMetaType::registerTypedef: "
+ "-- Type name '%s' previously registered as typedef of '%s' [%i], "
+ "now registering as typedef of '%s' [%i].",
+ normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
+ QMetaType::typeName(aliasId), aliasId);
}
return idx;
}
@@ -1841,6 +2085,37 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
\sa Q_DECLARE_METATYPE(), QMetaType::type()
*/
+/*!
+ \fn bool qRegisterSequentialConverter()
+ \relates QMetaType
+ \since 5.2
+
+ Registers a sequential container so that it can be converted to
+ a QVariantList. If compilation fails, then you probably forgot to
+ Q_DECLARE_METATYPE the value type.
+
+ Note that it is not necessary to call this method for Qt containers (QList,
+ QVector etc) or for std::vector or std::list. Such containers are automatically
+ registered by Qt.
+
+ \sa QVariant::canConvert()
+*/
+
+/*!
+ \fn bool qRegisterAssociativeConverter()
+ \relates QMetaType
+ \since 5.2
+
+ Registers an associative container so that it can be converted to
+ a QVariantHash or QVariantMap. If the key_type and mapped_type of the container
+ was not declared with Q_DECLARE_METATYPE(), compilation will fail.
+
+ Note that it is not necessary to call this method for Qt containers (QHash,
+ QMap etc) or for std::map. Such containers are automatically registered by Qt.
+
+ \sa QVariant::canConvert()
+*/
+
namespace {
class TypeInfo {
template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 5763bcc07b..6b1a988fce 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -47,17 +47,27 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qisenum.h>
+#include <QtCore/qtypetraits.h>
#ifndef QT_NO_QOBJECT
#include <QtCore/qobjectdefs.h>
#endif
#include <new>
+#include <vector>
+#include <list>
+#include <map>
+
#ifdef Bool
#error qmetatype.h must be included before any header file that defines Bool
#endif
QT_BEGIN_NAMESPACE
+template <typename T>
+struct QMetaTypeId2;
+
+template <typename T>
+inline Q_DECL_CONSTEXPR int qMetaTypeId();
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
@@ -183,10 +193,188 @@ QT_BEGIN_NAMESPACE
#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
TypeName = Id,
+#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
+ F(QList) \
+ F(QVector) \
+ F(QQueue) \
+ F(QStack) \
+ F(QSet) \
+ F(QLinkedList)
+
+#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
+ F(QHash, class) \
+ F(QMap, class) \
+ F(QPair, struct)
+
+#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
+ F(QSharedPointer) \
+ F(QWeakPointer) \
+ F(QPointer)
+
class QDataStream;
class QMetaTypeInterface;
struct QMetaObject;
+namespace QtPrivate
+{
+/*!
+ This template is used for implicit conversion from type From to type To.
+ \internal
+*/
+template<typename From, typename To>
+To convertImplicit(const From& from)
+{
+ return from;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+struct AbstractDebugStreamFunction
+{
+ typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *);
+ typedef void (*Destroy)(AbstractDebugStreamFunction *);
+ explicit AbstractDebugStreamFunction(Stream s = 0, Destroy d = 0)
+ : stream(s), destroy(d) {}
+ Q_DISABLE_COPY(AbstractDebugStreamFunction)
+ Stream stream;
+ Destroy destroy;
+};
+
+template<typename T>
+struct BuiltInDebugStreamFunction : public AbstractDebugStreamFunction
+{
+ BuiltInDebugStreamFunction()
+ : AbstractDebugStreamFunction(stream, destroy) {}
+ static void stream(const AbstractDebugStreamFunction *, QDebug& dbg, const void *r)
+ {
+ const T *rhs = static_cast<const T *>(r);
+ operator<<(dbg, *rhs);
+ }
+
+ static void destroy(AbstractDebugStreamFunction *_this)
+ {
+ delete static_cast<BuiltInDebugStreamFunction *>(_this);
+ }
+};
+#endif
+
+struct AbstractComparatorFunction
+{
+ typedef bool (*LessThan)(const AbstractComparatorFunction *, const void *, const void *);
+ typedef bool (*Equals)(const AbstractComparatorFunction *, const void *, const void *);
+ typedef void (*Destroy)(AbstractComparatorFunction *);
+ explicit AbstractComparatorFunction(LessThan lt = 0, Equals e = 0, Destroy d = 0)
+ : lessThan(lt), equals(e), destroy(d) {}
+ Q_DISABLE_COPY(AbstractComparatorFunction)
+ LessThan lessThan;
+ Equals equals;
+ Destroy destroy;
+};
+
+template<typename T>
+struct BuiltInComparatorFunction : public AbstractComparatorFunction
+{
+ BuiltInComparatorFunction()
+ : AbstractComparatorFunction(lessThan, equals, destroy) {}
+ static bool lessThan(const AbstractComparatorFunction *, const void *l, const void *r)
+ {
+ const T *lhs = static_cast<const T *>(l);
+ const T *rhs = static_cast<const T *>(r);
+ return *lhs < *rhs;
+ }
+
+ static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
+ {
+ const T *lhs = static_cast<const T *>(l);
+ const T *rhs = static_cast<const T *>(r);
+ return *lhs == *rhs;
+ }
+
+ static void destroy(AbstractComparatorFunction *_this)
+ {
+ delete static_cast<BuiltInComparatorFunction *>(_this);
+ }
+};
+
+struct AbstractConverterFunction
+{
+ typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);
+ explicit AbstractConverterFunction(Converter c = 0)
+ : convert(c) {}
+ Q_DISABLE_COPY(AbstractConverterFunction)
+ Converter convert;
+};
+
+template<typename From, typename To>
+struct ConverterMemberFunction : public AbstractConverterFunction
+{
+ explicit ConverterMemberFunction(To(From::*function)() const)
+ : AbstractConverterFunction(convert),
+ m_function(function) {}
+ ~ConverterMemberFunction();
+ static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
+ {
+ const From *f = static_cast<const From *>(in);
+ To *t = static_cast<To *>(out);
+ const ConverterMemberFunction *_typedThis =
+ static_cast<const ConverterMemberFunction *>(_this);
+ *t = (f->*_typedThis->m_function)();
+ return true;
+ }
+
+ To(From::* const m_function)() const;
+};
+
+template<typename From, typename To>
+struct ConverterMemberFunctionOk : public AbstractConverterFunction
+{
+ explicit ConverterMemberFunctionOk(To(From::*function)(bool *) const)
+ : AbstractConverterFunction(convert),
+ m_function(function) {}
+ ~ConverterMemberFunctionOk();
+ static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
+ {
+ const From *f = static_cast<const From *>(in);
+ To *t = static_cast<To *>(out);
+ bool ok = false;
+ const ConverterMemberFunctionOk *_typedThis =
+ static_cast<const ConverterMemberFunctionOk *>(_this);
+ *t = (f->*_typedThis->m_function)(&ok);
+ if (!ok)
+ *t = To();
+ return ok;
+ }
+
+ To(From::* const m_function)(bool*) const;
+};
+
+template<typename From, typename To, typename UnaryFunction>
+struct ConverterFunctor : public AbstractConverterFunction
+{
+ explicit ConverterFunctor(UnaryFunction function)
+ : AbstractConverterFunction(convert),
+ m_function(function) {}
+ ~ConverterFunctor();
+ static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
+ {
+ const From *f = static_cast<const From *>(in);
+ To *t = static_cast<To *>(out);
+ const ConverterFunctor *_typedThis =
+ static_cast<const ConverterFunctor *>(_this);
+ *t = _typedThis->m_function(*f);
+ return true;
+ }
+
+ UnaryFunction m_function;
+};
+
+ template<typename T, bool>
+ struct ValueTypeIsMetaType;
+ template<typename T, bool>
+ struct AssociativeValueTypeIsMetaType;
+ template<typename T, bool>
+ struct IsMetaTypePair;
+}
+
class Q_CORE_EXPORT QMetaType {
enum ExtensionFlag { NoExtensionFlags,
CreateEx = 0x1, DestroyEx = 0x2,
@@ -320,6 +508,109 @@ public:
inline void destroy(void *data) const;
inline void *construct(void *where, const void *copy = 0) const;
inline void destruct(void *data) const;
+
+public:
+ template<typename T>
+ static bool registerComparators()
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
+ "QMetaType::registerComparators: The type must be a custom type.");
+
+ const int typeId = qMetaTypeId<T>();
+ static const QtPrivate::BuiltInComparatorFunction<T> f;
+ return registerComparatorFunction( &f, typeId);
+ }
+ template<typename T>
+ static bool hasRegisteredComparators()
+ {
+ return hasRegisteredComparators(qMetaTypeId<T>());
+ }
+ static bool hasRegisteredComparators(int typeId);
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ template<typename T>
+ static bool registerDebugStreamOperator()
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
+ "QMetaType::registerDebugStreamOperator: The type must be a custom type.");
+
+ const int typeId = qMetaTypeId<T>();
+ static const QtPrivate::BuiltInDebugStreamFunction<T> f;
+ return registerDebugStreamOperatorFunction(&f, typeId);
+ }
+ template<typename T>
+ static bool hasRegisteredDebugStreamOperator()
+ {
+ return hasRegisteredDebugStreamOperator(qMetaTypeId<T>());
+ }
+ static bool hasRegisteredDebugStreamOperator(int typeId);
+#endif
+
+ // implicit conversion supported like double -> float
+ template<typename From, typename To>
+ static bool registerConverter()
+ {
+ return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>);
+ }
+
+#ifdef Q_QDOC
+ static bool registerConverter(MemberFunction function);
+ static bool registerConverter(MemberFunctionOk function);
+ static bool registerConverter(UnaryFunction function);
+#else
+ // member function as in "QString QFont::toString() const"
+ template<typename From, typename To>
+ static bool registerConverter(To(From::*function)() const)
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
+ "QMetaType::registerConverter: At least one of the types must be a custom type.");
+
+ const int fromTypeId = qMetaTypeId<From>();
+ const int toTypeId = qMetaTypeId<To>();
+ static const QtPrivate::ConverterMemberFunction<From, To> f(function);
+ return registerConverterFunction(&f, fromTypeId, toTypeId);
+ }
+
+ // member function as in "double QString::toDouble(bool *ok = 0) const"
+ template<typename From, typename To>
+ static bool registerConverter(To(From::*function)(bool*) const)
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
+ "QMetaType::registerConverter: At least one of the types must be a custom type.");
+
+ const int fromTypeId = qMetaTypeId<From>();
+ const int toTypeId = qMetaTypeId<To>();
+ static const QtPrivate::ConverterMemberFunctionOk<From, To> f(function);
+ return registerConverterFunction(&f, fromTypeId, toTypeId);
+ }
+
+ // functor or function pointer
+ template<typename From, typename To, typename UnaryFunction>
+ static bool registerConverter(UnaryFunction function)
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
+ "QMetaType::registerConverter: At least one of the types must be a custom type.");
+
+ const int fromTypeId = qMetaTypeId<From>();
+ const int toTypeId = qMetaTypeId<To>();
+ static const QtPrivate::ConverterFunctor<From, To, UnaryFunction> f(function);
+ return registerConverterFunction(&f, fromTypeId, toTypeId);
+ }
+#endif
+
+ static bool convert(const void *from, int fromTypeId, void *to, int toTypeId);
+ static bool compare(const void *lhs, const void *rhs, int typeId, int* result);
+ static bool debugStream(QDebug& dbg, const void *rhs, int typeId);
+
+ template<typename From, typename To>
+ static bool hasRegisteredConverterFunction()
+ {
+ return hasRegisteredConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+ }
+
+ static bool hasRegisteredConverterFunction(int fromTypeId, int toTypeId);
+
private:
static QMetaType typeInfo(const int type);
inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
@@ -348,6 +639,31 @@ private:
void *constructExtended(void *where, const void *copy = 0) const;
void destructExtended(void *data) const;
+ static bool registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type);
+#ifndef QT_NO_DEBUG_STREAM
+ static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type);
+#endif
+
+#ifndef Q_NO_TEMPLATE_FRIENDS
+#ifndef Q_QDOC
+ template<typename T>
+ friend bool qRegisterSequentialConverter();
+ template<typename, bool> friend struct QtPrivate::ValueTypeIsMetaType;
+ template<typename, typename> friend struct QtPrivate::ConverterMemberFunction;
+ template<typename, typename> friend struct QtPrivate::ConverterMemberFunctionOk;
+ template<typename, typename, typename> friend struct QtPrivate::ConverterFunctor;
+ template<typename T>
+ friend bool qRegisterAssociativeConverter();
+ template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
+ template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
+#endif
+#else
+public:
+#endif
+ static bool registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to);
+ static void unregisterConverterFunction(int from, int to);
+private:
+
Creator m_creator;
Deleter m_deleter;
SaveOperator m_saveOp;
@@ -366,6 +682,26 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
+namespace QtPrivate {
+
+template<typename From, typename To>
+ConverterMemberFunction<From, To>::~ConverterMemberFunction()
+{
+ QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+}
+template<typename From, typename To>
+ConverterMemberFunctionOk<From, To>::~ConverterMemberFunctionOk()
+{
+ QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+}
+template<typename From, typename To, typename UnaryFunction>
+ConverterFunctor<From, To, UnaryFunction>::~ConverterFunctor()
+{
+ QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+}
+
+}
+
namespace QtMetaTypePrivate {
template <typename T, bool Accepted = true>
struct QMetaTypeFunctionHelper {
@@ -421,13 +757,493 @@ template <>
struct QMetaTypeFunctionHelper<void, /* Accepted */ true>
: public QMetaTypeFunctionHelper<void, /* Accepted */ false>
{};
+
+struct VariantData
+{
+ VariantData(const int metaTypeId_,
+ const void *data_,
+ const uint flags_)
+ : metaTypeId(metaTypeId_)
+ , data(data_)
+ , flags(flags_)
+ {
+ }
+ const int metaTypeId;
+ const void *data;
+ const uint flags;
+};
+
+template<typename const_iterator>
+struct IteratorOwner
+{
+ static void assign(void **ptr, const_iterator iterator)
+ {
+ *ptr = new const_iterator(iterator);
+ }
+
+ static void advance(void **iterator, int step)
+ {
+ const_iterator &it = *static_cast<const_iterator*>(*iterator);
+ std::advance(it, step);
+ }
+
+ static void destroy(void **ptr)
+ {
+ delete static_cast<const_iterator*>(*ptr);
+ }
+
+ static const void *getData(void * const *iterator)
+ {
+ return &**static_cast<const_iterator*>(*iterator);
+ }
+
+ static const void *getData(const_iterator it)
+ {
+ return &*it;
+ }
+};
+template<typename const_iterator>
+struct IteratorOwner<const const_iterator*>
+{
+ static void assign(void **ptr, const const_iterator *iterator )
+ {
+ *ptr = const_cast<const_iterator*>(iterator);
+ }
+
+ static void advance(void **iterator, int step)
+ {
+ const_iterator *it = static_cast<const_iterator*>(*iterator);
+ std::advance(it, step);
+ *iterator = it;
+ }
+
+ static void destroy(void **)
+ {
+ }
+
+ static const void *getData(void * const *iterator)
+ {
+ return *iterator;
+ }
+
+ static const void *getData(const const_iterator *it)
+ {
+ return it;
+ }
+};
+
+enum IteratorCapability
+{
+ ForwardCapability = 1,
+ BiDirectionalCapability = 2,
+ RandomAccessCapability = 4
+};
+
+template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
+struct CapabilitiesImpl;
+
+template<typename T>
+struct CapabilitiesImpl<T, std::forward_iterator_tag>
+{ enum { IteratorCapabilities = ForwardCapability }; };
+template<typename T>
+struct CapabilitiesImpl<T, std::bidirectional_iterator_tag>
+{ enum { IteratorCapabilities = BiDirectionalCapability | ForwardCapability }; };
+template<typename T>
+struct CapabilitiesImpl<T, std::random_access_iterator_tag>
+{ enum { IteratorCapabilities = RandomAccessCapability | BiDirectionalCapability | ForwardCapability }; };
+
+template<typename T>
+struct ContainerAPI : CapabilitiesImpl<T>
+{
+ static int size(const T *t) { return std::distance(t->begin(), t->end()); }
+};
+
+template<typename T>
+struct ContainerAPI<QList<T> > : CapabilitiesImpl<QList<T> >
+{ static int size(const QList<T> *t) { return t->size(); } };
+
+template<typename T>
+struct ContainerAPI<QVector<T> > : CapabilitiesImpl<QVector<T> >
+{ static int size(const QVector<T> *t) { return t->size(); } };
+
+template<typename T>
+struct ContainerAPI<std::vector<T> > : CapabilitiesImpl<std::vector<T> >
+{ static int size(const std::vector<T> *t) { return t->size(); } };
+
+template<typename T>
+struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> >
+{ static int size(const std::list<T> *t) { return t->size(); } };
+
+class QSequentialIterableImpl
+{
+public:
+ const void * _iterable;
+ void *_iterator;
+ int _metaType_id;
+ uint _metaType_flags;
+ uint _iteratorCapabilities;
+ typedef int(*sizeFunc)(const void *p);
+ typedef const void * (*atFunc)(const void *p, int);
+ typedef void (*moveIteratorFunc)(const void *p, void **);
+ typedef void (*advanceFunc)(void **p, int);
+ typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
+ typedef void (*destroyIterFunc)(void **p);
+ typedef bool (*equalIterFunc)(void * const *p, void * const *other);
+
+ sizeFunc _size;
+ atFunc _at;
+ moveIteratorFunc _moveToBegin;
+ moveIteratorFunc _moveToEnd;
+ advanceFunc _advance;
+ getFunc _get;
+ destroyIterFunc _destroyIter;
+ equalIterFunc _equalIter;
+
+ template<class T>
+ static int sizeImpl(const void *p)
+ { return ContainerAPI<T>::size(static_cast<const T*>(p)); }
+
+ template<class T>
+ static const void* atImpl(const void *p, int idx)
+ {
+ typename T::const_iterator i = static_cast<const T*>(p)->begin();
+ std::advance(i, idx);
+ return IteratorOwner<typename T::const_iterator>::getData(i);
+ }
+
+ template<class T>
+ static void advanceImpl(void **p, int step)
+ { IteratorOwner<typename T::const_iterator>::advance(p, step); }
+
+ template<class T>
+ static void moveToBeginImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
+
+ template<class T>
+ static void moveToEndImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
+
+ template<class T>
+ static void destroyIterImpl(void **iterator)
+ { IteratorOwner<typename T::const_iterator>::destroy(iterator); }
+
+ template<class T>
+ static bool equalIterImpl(void * const *iterator, void * const *other)
+ { return *static_cast<typename T::const_iterator*>(*iterator) == *static_cast<typename T::const_iterator*>(*other); }
+
+ template<class T>
+ static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
+
+public:
+ template<class T> QSequentialIterableImpl(const T*p)
+ : _iterable(p)
+ , _iterator(0)
+ , _metaType_id(qMetaTypeId<typename T::value_type>())
+ , _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
+ , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities)
+ , _size(sizeImpl<T>)
+ , _at(atImpl<T>)
+ , _moveToBegin(moveToBeginImpl<T>)
+ , _moveToEnd(moveToEndImpl<T>)
+ , _advance(advanceImpl<T>)
+ , _get(getImpl<T>)
+ , _destroyIter(destroyIterImpl<T>)
+ , _equalIter(equalIterImpl<T>)
+ {
+ }
+
+ QSequentialIterableImpl()
+ : _iterable(0)
+ , _iterator(0)
+ , _metaType_id(QMetaType::UnknownType)
+ , _metaType_flags(0)
+ , _iteratorCapabilities(0)
+ , _size(0)
+ , _at(0)
+ , _moveToBegin(0)
+ , _moveToEnd(0)
+ , _advance(0)
+ , _get(0)
+ , _destroyIter(0)
+ , _equalIter(0)
+ {
+ }
+
+ inline void moveToBegin() { _moveToBegin(_iterable, &_iterator); }
+ inline void moveToEnd() { _moveToEnd(_iterable, &_iterator); }
+ inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
+ inline QSequentialIterableImpl &advance(int i) {
+ Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability);
+ _advance(&_iterator, i);
+ return *this;
+ }
+
+ inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); }
+
+ VariantData at(int idx) const
+ { return VariantData(_metaType_id, _at(_iterable, idx), _metaType_flags); }
+
+ int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
+
+ inline void destroyIter() { _destroyIter(&_iterator); }
+};
+
+template<typename From>
+struct QSequentialIterableConvertFunctor
+{
+ QSequentialIterableConvertFunctor() {}
+
+ QSequentialIterableImpl operator()(const From &f) const
+ {
+ return QSequentialIterableImpl(&f);
+ }
+};
+}
+
+namespace QtMetaTypePrivate {
+template<typename T, bool = QtPrivate::is_same<typename T::const_iterator::value_type, typename T::mapped_type>::value>
+struct AssociativeContainerAccessor
+{
+ static const typename T::key_type& getKey(const typename T::const_iterator &it)
+ {
+ return it.key();
+ }
+
+ static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
+ {
+ return it.value();
+ }
+};
+
+template<typename T, bool = QtPrivate::is_same<typename T::const_iterator::value_type, std::pair<const typename T::key_type, typename T::mapped_type> >::value>
+struct StlStyleAssociativeContainerAccessor;
+
+template<typename T>
+struct StlStyleAssociativeContainerAccessor<T, true>
+{
+ static const typename T::key_type& getKey(const typename T::const_iterator &it)
+ {
+ return it->first;
+ }
+
+ static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
+ {
+ return it->second;
+ }
+};
+
+template<typename T>
+struct AssociativeContainerAccessor<T, false> : public StlStyleAssociativeContainerAccessor<T>
+{
+};
+
+class QAssociativeIterableImpl
+{
+public:
+ const void *_iterable;
+ void *_iterator;
+ int _metaType_id_key;
+ uint _metaType_flags_key;
+ int _metaType_id_value;
+ uint _metaType_flags_value;
+ typedef int(*sizeFunc)(const void *p);
+ typedef void (*findFunc)(const void *container, const void *p, void **iterator);
+ typedef void (*beginFunc)(const void *p, void **);
+ typedef void (*advanceFunc)(void **p, int);
+ typedef VariantData (*getFunc)(void * const *p, int metaTypeId, uint flags);
+ typedef void (*destroyIterFunc)(void **p);
+ typedef bool (*equalIterFunc)(void * const *p, void * const *other);
+
+ sizeFunc _size;
+ findFunc _find;
+ beginFunc _begin;
+ beginFunc _end;
+ advanceFunc _advance;
+ getFunc _getKey;
+ getFunc _getValue;
+ destroyIterFunc _destroyIter;
+ equalIterFunc _equalIter;
+
+ template<class T>
+ static int sizeImpl(const void *p)
+ { return std::distance(static_cast<const T*>(p)->begin(),
+ static_cast<const T*>(p)->end()); }
+
+ template<class T>
+ static void findImpl(const void *container, const void *p, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator,
+ static_cast<const T*>(container)->find(*static_cast<const typename T::key_type*>(p))); }
+
+ template<class T>
+ static void advanceImpl(void **p, int step)
+ { std::advance(*static_cast<typename T::const_iterator*>(*p), step); }
+
+ template<class T>
+ static void beginImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
+
+ template<class T>
+ static void endImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
+
+ template<class T>
+ static VariantData getKeyImpl(void * const *iterator, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getKey(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
+
+ template<class T>
+ static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
+
+ template<class T>
+ static void destroyIterImpl(void **iterator)
+ { IteratorOwner<typename T::const_iterator>::destroy(iterator); }
+
+ template<class T>
+ static bool equalIterImpl(void * const *iterator, void * const *other)
+ { return *static_cast<typename T::const_iterator*>(*iterator) == *static_cast<typename T::const_iterator*>(*other); }
+
+public:
+ template<class T> QAssociativeIterableImpl(const T*p)
+ : _iterable(p)
+ , _metaType_id_key(qMetaTypeId<typename T::key_type>())
+ , _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
+ , _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
+ , _metaType_flags_value(QTypeInfo<typename T::mapped_type>::isPointer)
+ , _size(sizeImpl<T>)
+ , _find(findImpl<T>)
+ , _begin(beginImpl<T>)
+ , _end(endImpl<T>)
+ , _advance(advanceImpl<T>)
+ , _getKey(getKeyImpl<T>)
+ , _getValue(getValueImpl<T>)
+ , _destroyIter(destroyIterImpl<T>)
+ , _equalIter(equalIterImpl<T>)
+ {
+ }
+
+ QAssociativeIterableImpl()
+ : _iterable(0)
+ , _metaType_id_key(QMetaType::UnknownType)
+ , _metaType_flags_key(0)
+ , _metaType_id_value(QMetaType::UnknownType)
+ , _metaType_flags_value(0)
+ , _size(0)
+ , _find(0)
+ , _begin(0)
+ , _end(0)
+ , _advance(0)
+ , _getKey(0)
+ , _getValue(0)
+ , _destroyIter(0)
+ , _equalIter(0)
+ {
+ }
+
+ inline void begin() { _begin(_iterable, &_iterator); }
+ inline void end() { _end(_iterable, &_iterator); }
+ inline bool equal(const QAssociativeIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
+ inline QAssociativeIterableImpl &advance(int i) { _advance(&_iterator, i); return *this; }
+
+ inline void destroyIter() { _destroyIter(&_iterator); }
+
+ inline VariantData getCurrentKey() const { return _getKey(&_iterator, _metaType_id_key, _metaType_flags_value); }
+ inline VariantData getCurrentValue() const { return _getValue(&_iterator, _metaType_id_value, _metaType_flags_value); }
+
+ inline void find(const VariantData &key)
+ { _find(_iterable, key.data, &_iterator); }
+
+ int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
+};
+
+template<typename From>
+struct QAssociativeIterableConvertFunctor
+{
+ QAssociativeIterableConvertFunctor() {}
+
+ QAssociativeIterableImpl operator()(const From& f) const
+ {
+ return QAssociativeIterableImpl(&f);
+ }
+};
+
+class QPairVariantInterfaceImpl
+{
+ const void *_pair;
+ int _metaType_id_first;
+ uint _metaType_flags_first;
+ int _metaType_id_second;
+ uint _metaType_flags_second;
+
+ typedef VariantData (*getFunc)(const void * const *p, int metaTypeId, uint flags);
+
+ getFunc _getFirst;
+ getFunc _getSecond;
+
+ template<class T>
+ static VariantData getFirstImpl(const void * const *pair, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->first, flags); }
+ template<class T>
+ static VariantData getSecondImpl(const void * const *pair, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->second, flags); }
+
+public:
+ template<class T> QPairVariantInterfaceImpl(const T*p)
+ : _pair(p)
+ , _metaType_id_first(qMetaTypeId<typename T::first_type>())
+ , _metaType_flags_first(QTypeInfo<typename T::first_type>::isPointer)
+ , _metaType_id_second(qMetaTypeId<typename T::second_type>())
+ , _metaType_flags_second(QTypeInfo<typename T::second_type>::isPointer)
+ , _getFirst(getFirstImpl<T>)
+ , _getSecond(getSecondImpl<T>)
+ {
+ }
+
+ QPairVariantInterfaceImpl()
+ : _pair(0)
+ , _getFirst(0)
+ , _getSecond(0)
+ {
+ }
+
+ inline VariantData first() const { return _getFirst(&_pair, _metaType_id_first, _metaType_flags_first); }
+ inline VariantData second() const { return _getSecond(&_pair, _metaType_id_second, _metaType_flags_second); }
+};
+
+template<typename From>
+struct QPairVariantInterfaceConvertFunctor;
+
+template<typename T, typename U>
+struct QPairVariantInterfaceConvertFunctor<QPair<T, U> >
+{
+ QPairVariantInterfaceConvertFunctor() {}
+
+ QPairVariantInterfaceImpl operator()(const QPair<T, U>& f) const
+ {
+ return QPairVariantInterfaceImpl(&f);
+ }
+};
+
+template<typename T, typename U>
+struct QPairVariantInterfaceConvertFunctor<std::pair<T, U> >
+{
+ QPairVariantInterfaceConvertFunctor() {}
+
+ QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const
+ {
+ return QPairVariantInterfaceImpl(&f);
+ }
+};
+
}
class QObject;
class QWidget;
-template <class T> class QSharedPointer;
-template <class T> class QWeakPointer;
-template <class T> class QPointer;
+
+#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
+ template <class T> class Name; \
+
+QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER)
namespace QtPrivate
{
@@ -509,6 +1325,165 @@ namespace QtPrivate
enum { Value = true };
};
+ template<typename T>
+ struct IsSequentialContainer
+ {
+ enum { Value = false };
+ };
+
+#define QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(CONTAINER) \
+ template<typename T> \
+ struct IsSequentialContainer<CONTAINER<T> > \
+ { \
+ enum { Value = true }; \
+ };
+ QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE)
+ QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(std::vector)
+ QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(std::list)
+
+ template<typename T>
+ struct IsAssociativeContainer
+ {
+ enum { Value = false };
+ };
+
+#define QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(CONTAINER) \
+ template<typename T, typename U> \
+ struct IsAssociativeContainer<CONTAINER<T, U> > \
+ { \
+ enum { Value = true }; \
+ };
+ QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(QHash)
+ QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(QMap)
+ QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(std::map)
+
+
+ template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
+ struct SequentialContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
+ struct ValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct ValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ static const QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QSequentialIterableImpl,
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+
+ template<typename T>
+ struct SequentialContainerConverterHelper<T, true> : ValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
+ struct AssociativeContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
+ struct AssociativeValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct AssociativeValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ static const QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QAssociativeIterableImpl,
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
+ struct KeyAndValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct KeyAndValueTypeIsMetaType<T, true> : AssociativeValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T>
+ struct AssociativeContainerConverterHelper<T, true> : KeyAndValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
+ && QMetaTypeId2<typename T::second_type>::Defined>
+ struct IsMetaTypePair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct IsMetaTypePair<T, true>
+ {
+ inline static bool registerConverter(int id);
+ };
+
+ template<typename T>
+ struct IsPair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+ template<typename T, typename U>
+ struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {};
+ template<typename T, typename U>
+ struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
+
+ template<typename T>
+ struct MetaTypePairHelper : IsPair<T> {};
+
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
@@ -546,11 +1521,16 @@ namespace QtPrivate {
{ return -1; }
};
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
// Function pointers don't derive from QObject
template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
+#else
+ template <typename Result, typename... Args>
+ struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
+#endif
template<typename T>
struct QMetaTypeTypeFlags
@@ -593,7 +1573,7 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
if (defined)
flags |= QMetaType::WasDeclaredAsMetaType;
- return QMetaType::registerNormalizedType(normalizedTypeName,
+ const int id = QMetaType::registerNormalizedType(normalizedTypeName,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Delete,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Create,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
@@ -601,6 +1581,14 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
int(sizeof(T)),
flags,
QtPrivate::MetaObjectForType<T>::value());
+
+ if (id > 0) {
+ QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
+ }
+
+ return id;
}
template <typename T>
@@ -746,6 +1734,7 @@ typedef QMap<QString, QVariant> QVariantMap;
typedef QHash<QString, QVariant> QVariantHash;
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
+QT_BEGIN_NAMESPACE \
template <typename T> \
struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
{ \
@@ -773,9 +1762,11 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
metatype_id.storeRelease(newId); \
return newId; \
} \
-};
+}; \
+QT_END_NAMESPACE
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
+QT_BEGIN_NAMESPACE \
template<typename T, typename U> \
struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
{ \
@@ -806,19 +1797,30 @@ struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
metatype_id.storeRelease(newId); \
return newId; \
} \
+}; \
+QT_END_NAMESPACE
+
+namespace QtPrivate {
+
+template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
+struct SharedPointerMetaTypeIdHelper
+{
+ enum {
+ Defined = 0
+ };
+ static int qt_metatype_id()
+ {
+ return -1;
+ }
};
+}
+
#define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
-template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
-struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar \
-{ \
- enum { \
- Defined = 0 \
- }; \
-};\
- \
-template <typename T> \
-struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
+QT_BEGIN_NAMESPACE \
+namespace QtPrivate { \
+template<typename T> \
+struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
{ \
enum { \
Defined = 1 \
@@ -840,51 +1842,51 @@ struct QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T, true> \
return newId; \
} \
}; \
-\
+} \
template <typename T> \
-struct QMetaTypeId< SMART_POINTER<T> > : public QMetaTypeId_ ## SMART_POINTER ## _QObjectStar<T> \
+struct QMetaTypeId< SMART_POINTER<T> > \
+ : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
+ QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
{ \
-};
-
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
- F(QList) \
- F(QVector) \
- F(QQueue) \
- F(QStack) \
- F(QSet) \
- F(QLinkedList)
-
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
- F(QHash, class) \
- F(QMap, class) \
- F(QPair, struct)
-
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
- F(QSharedPointer) \
- F(QWeakPointer) \
- F(QPointer)
+};\
+QT_END_NAMESPACE
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER(TEMPLATENAME) \
+ QT_BEGIN_NAMESPACE \
template <class T> class TEMPLATENAME; \
+ QT_END_NAMESPACE \
Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME)
+QT_END_NAMESPACE
+
QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER)
#undef Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER
+Q_DECLARE_METATYPE_TEMPLATE_1ARG(std::vector)
+Q_DECLARE_METATYPE_TEMPLATE_1ARG(std::list)
+
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
+ QT_BEGIN_NAMESPACE \
template <class T1, class T2> CPPTYPE TEMPLATENAME; \
+ QT_END_NAMESPACE \
Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
#undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::map)
+
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
+
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
+QT_BEGIN_NAMESPACE
+
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
@@ -987,5 +1989,65 @@ QT_END_NAMESPACE
QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QSequentialIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
+
+QT_BEGIN_NAMESPACE
+
+template <typename T>
+inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter(int id)
+{
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ static const QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QPairVariantInterfaceImpl,
+ QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+}
+
+
+#ifndef Q_QDOC
+template<typename T>
+#endif
+bool qRegisterSequentialConverter()
+{
+ Q_STATIC_ASSERT_X(QMetaTypeId2<typename T::value_type>::Defined,
+ "The value_type of a sequential container must itself be a metatype.");
+ const int id = qMetaTypeId<T>();
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (QMetaType::hasRegisteredConverterFunction(id, toId))
+ return true;
+
+ static const QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QSequentialIterableImpl,
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+}
+
+template<typename T>
+bool qRegisterAssociativeConverter()
+{
+ Q_STATIC_ASSERT_X(QMetaTypeId2<typename T::key_type>::Defined
+ && QMetaTypeId2<typename T::mapped_type>::Defined,
+ "The key_type and mapped_type of an associative container must themselves be metatypes.");
+
+ const int id = qMetaTypeId<T>();
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
+ if (QMetaType::hasRegisteredConverterFunction(id, toId))
+ return true;
+ static const QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QAssociativeIterableImpl,
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
+
+ return QMetaType::registerConverterFunction(&f, id, toId);
+}
+
+QT_END_NAMESPACE
#endif // QMETATYPE_H
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 33e2adf5ba..b914ca812f 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2346,6 +2346,7 @@ void QMetaObjectPrivate::memberIndexes(const QObject *obj,
}
}
+#ifndef QT_NO_DEBUG
static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
const QMetaObject *receiver, const QMetaMethod &method)
{
@@ -2360,6 +2361,7 @@ static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaM
receiver->className(), method.methodSignature().constData());
}
}
+#endif
/*!
\threadsafe
@@ -4270,7 +4272,7 @@ void qDeleteInEventHandler(QObject *o)
must not have an overloaded or templated operator().
*/
-/**
+/*!
\internal
Implementation of the template version of connect
@@ -4295,12 +4297,13 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject)
{
- if (!sender || !signal || !slotObj || !senderMetaObject) {
+ if (!signal) {
qWarning("QObject::connect: invalid null parameter");
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
}
+
int signal_index = -1;
void *args[] = { &signal_index, signal };
for (; senderMetaObject && signal_index < 0; senderMetaObject = senderMetaObject->superClass()) {
@@ -4314,6 +4317,27 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
return QMetaObject::Connection(0);
}
signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
+ return QObjectPrivate::connectImpl(sender, signal_index, receiver, slot, slotObj, type, types, senderMetaObject);
+}
+
+/*!
+ \internal
+
+ Internal version of connect used by the template version of QObject::connect (called via connectImpl) and
+ also used by the QObjectPrivate::connect version used by QML. The signal_index is expected to be relative
+ to the number of signals.
+ */
+QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int signal_index,
+ const QObject *receiver, void **slot,
+ QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
+ const int *types, const QMetaObject *senderMetaObject)
+{
+ if (!sender || !slotObj || !senderMetaObject) {
+ qWarning("QObject::connect: invalid null parameter");
+ if (slotObj)
+ slotObj->destroyIfLastRef();
+ return QMetaObject::Connection();
+ }
QObject *s = const_cast<QObject *>(sender);
QObject *r = const_cast<QObject *>(receiver);
@@ -4487,6 +4511,40 @@ bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject
return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, receiver, -1, slot);
}
+/*!
+ \internal
+ Used by QML to connect a signal by index to a slot implemented in JavaScript (wrapped in a custom QSlotOBjectBase subclass).
+
+ The signal_index is an index relative to the number of methods.
+ */
+QMetaObject::Connection QObjectPrivate::connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type)
+{
+ if (!sender) {
+ qWarning("QObject::connect: invalid null parameter");
+ if (slotObj)
+ slotObj->destroyIfLastRef();
+ return QMetaObject::Connection();
+ }
+ const QMetaObject *senderMetaObject = sender->metaObject();
+ signal_index = methodIndexToSignalIndex(&senderMetaObject, signal_index);
+
+ return QObjectPrivate::connectImpl(sender, signal_index, sender, /*slot*/0, slotObj, type, /*types*/0, senderMetaObject);
+}
+
+/*!
+ \internal
+ Used by QML to disconnect a signal by index that's connected to a slot implemented in JavaScript (wrapped in a custom QSlotObjectBase subclass)
+ In the QML case the slot is not a pointer to a pointer to the function to disconnect, but instead it is a pointer to an array of internal values
+ required for the disconnect.
+ */
+bool QObjectPrivate::disconnect(const QObject *sender, int signal_index, void **slot)
+{
+ const QMetaObject *senderMetaObject = sender->metaObject();
+ signal_index = methodIndexToSignalIndex(&senderMetaObject, signal_index);
+
+ return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, sender, -1, slot);
+}
+
/*! \class QMetaObject::Connection
\inmodule QtCore
Represents a handle to a signal-slot connection.
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index e849ec1599..3c43972ac9 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -207,6 +207,13 @@ public:
template <typename Func1, typename Func2>
static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot);
+
+ static QMetaObject::Connection connectImpl(const QObject *sender, int signal_index,
+ const QObject *receiver, void **slot,
+ QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
+ const int *types, const QMetaObject *senderMetaObject);
+ static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type);
+ static bool disconnect(const QObject *sender, int signal_index, void **slot);
public:
ExtraData *extraData; // extra data set by the user
QThreadData *threadData; // id of the thread that owns the object
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index afbe1a5ece..c489344b10 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -456,6 +456,7 @@ class Q_CORE_EXPORT QMetaObject::Connection {
void *d_ptr; //QObjectPrivate::Connection*
explicit Connection(void *data) : d_ptr(data) { }
friend class QObject;
+ friend class QObjectPrivate;
friend struct QMetaObject;
public:
~Connection();
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index e0c7f171c3..6c88ed4531 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -181,17 +181,16 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent)
: QObject(*new QSocketNotifierPrivate, parent)
{
Q_D(QSocketNotifier);
- if (socket < 0)
- qWarning("QSocketNotifier: Invalid socket specified");
d->sockfd = socket;
d->sntype = type;
d->snenabled = true;
- if (!d->threadData->eventDispatcher.load()) {
+ if (socket < 0)
+ qWarning("QSocketNotifier: Invalid socket specified");
+ else if (!d->threadData->eventDispatcher.load())
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
- } else {
+ else
d->threadData->eventDispatcher.load()->registerSocketNotifier(this);
- }
}
/*!
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 276257ddcf..c3ccc74a20 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -269,6 +269,16 @@ inline bool qt_convertToBool(const QVariant::Private *const d)
/*!
\internal
+ Returns the internal data pointer from \a d.
+ */
+
+static const void *constData(const QVariant::Private &d)
+{
+ return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.c);
+}
+
+/*!
+ \internal
Converts \a d to type \a t, which is placed in \a result.
*/
@@ -277,6 +287,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
Q_ASSERT(d->type != uint(t));
Q_ASSERT(result);
+ if (d->type >= QMetaType::User || t >= QMetaType::User) {
+ const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
+ if (ok)
+ *ok = isOk;
+ if (isOk)
+ return true;
+ }
+
bool dummy;
if (!ok)
ok = &dummy;
@@ -867,8 +885,15 @@ static bool customCompare(const QVariant::Private *a, const QVariant::Private *b
return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
}
-static bool customConvert(const QVariant::Private *, int, void *, bool *ok)
+static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
{
+ if (d->type >= QMetaType::User || t >= QMetaType::User) {
+ const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
+ if (ok)
+ *ok = isOk;
+ return isOk;
+ }
+
if (ok)
*ok = false;
return false;
@@ -1958,6 +1983,12 @@ inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &han
return *v_cast<T>(&d);
T ret;
+ if (d.type >= QMetaType::User || targetType >= QMetaType::User) {
+ const void * const from = constData(d);
+ if (QMetaType::convert(from, d.type, &ret, targetType))
+ return ret;
+ }
+
handlerManager[d.type]->convert(&d, targetType, &ret, 0);
return ret;
}
@@ -2374,13 +2405,19 @@ template <typename T>
inline T qNumVariantToHelper(const QVariant::Private &d,
const HandlersManager &handlerManager, bool *ok, const T& val)
{
- uint t = qMetaTypeId<T>();
+ const uint t = qMetaTypeId<T>();
if (ok)
*ok = true;
+
if (d.type == t)
return val;
T ret = 0;
+ if ((d.type >= QMetaType::User || t >= QMetaType::User)
+ && QMetaType::convert(&val, d.type, &ret, t)) {
+ return ret;
+ }
+
if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
*ok = false;
return ret;
@@ -2735,10 +2772,52 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject)
function if a qobject_cast to the type described by \a targetTypeId would succeed. Note that
this only works for QObject subclasses which use the Q_OBJECT macro.
- \sa convert()
+ A QVariant containing a sequential container will also return true for this
+ function if the \a targetTypeId is QVariantList. It is possible to iterate over
+ the contents of the container without extracting it as a (copied) QVariantList:
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ This requires that the value_type of the container is itself a metatype.
+
+ Similarly, a QVariant containing a sequential container will also return true for this
+ function the \a targetTypeId is QVariantHash or QVariantMap. It is possible to iterate over
+ the contents of the container without extracting it as a (copied) QVariantHash or QVariantMap:
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ \sa convert(), QSequentialIterable, qRegisterSequentialConverter(), QAssociativeIterable,
+ qRegisterAssociativeConverter()
*/
bool QVariant::canConvert(int targetTypeId) const
{
+ if (targetTypeId == QMetaType::QVariantList
+ && (d.type == QMetaType::QVariantList
+ || d.type == QMetaType::QStringList
+ || QMetaType::hasRegisteredConverterFunction(d.type,
+ qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()))) {
+ return true;
+ }
+
+ if ((targetTypeId == QMetaType::QVariantHash || targetTypeId == QMetaType::QVariantMap)
+ && (d.type == QMetaType::QVariantMap
+ || d.type == QMetaType::QVariantHash
+ || QMetaType::hasRegisteredConverterFunction(d.type,
+ qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()))) {
+ return true;
+ }
+
+ if (targetTypeId == qMetaTypeId<QPair<QVariant, QVariant> >() &&
+ QMetaType::hasRegisteredConverterFunction(d.type,
+ qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ return true;
+ }
+
+ if ((d.type >= QMetaType::User || targetTypeId >= QMetaType::User)
+ && QMetaType::hasRegisteredConverterFunction(d.type, targetTypeId)) {
+ return true;
+ }
+
// TODO Reimplement this function, currently it works but it is a historical mess.
uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
if (currentType == QMetaType::SChar || currentType == QMetaType::Char)
@@ -2867,7 +2946,7 @@ bool QVariant::convert(int targetTypeId)
if (oldValue.isNull())
return false;
- if ((QMetaType::typeFlags(d.type) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {
+ if ((QMetaType::typeFlags(oldValue.userType()) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {
create(targetTypeId, &oldValue.d.data.o);
return true;
}
@@ -2886,7 +2965,6 @@ bool QVariant::convert(int targetTypeId)
*/
bool QVariant::convert(const int type, void *ptr) const
{
- Q_ASSERT(type < int(QMetaType::User));
return handlerManager[type]->convert(&d, type, ptr, 0);
}
@@ -2908,8 +2986,9 @@ bool QVariant::convert(const int type, void *ptr) const
which means that two values can be equal even if one of them is null and
another is not.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
/*!
\fn bool operator!=(const QVariant &v1, const QVariant &v2)
@@ -2918,8 +2997,9 @@ bool QVariant::convert(const int type, void *ptr) const
Returns false if \a v1 and \a v2 are equal; otherwise returns true.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
/*! \fn bool QVariant::operator==(const QVariant &v) const
@@ -2932,8 +3012,9 @@ bool QVariant::convert(const int type, void *ptr) const
type is not the same as this variant's type. See canConvert() for
a list of possible conversions.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
/*!
@@ -2942,8 +3023,61 @@ bool QVariant::convert(const int type, void *ptr) const
Compares this QVariant with \a v and returns true if they are not
equal; otherwise returns false.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator<(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is less than \a v.
+
+ \note Comparability might not be availabe for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator<=(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is less or equal than \a v.
+
+ \note Comparability might not be available for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator>(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is larger than \a v.
+
+ \note Comparability might not be available for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator>=(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is larger or equal than \a v.
+
+ \note Comparability might not be available for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
static bool qIsNumericType(uint tp)
@@ -2962,6 +3096,7 @@ static bool qIsFloatingPoint(uint tp)
*/
bool QVariant::cmp(const QVariant &v) const
{
+ QVariant v1 = *this;
QVariant v2 = v;
if (d.type != v2.d.type) {
if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) {
@@ -2970,10 +3105,63 @@ bool QVariant::cmp(const QVariant &v) const
else
return toLongLong() == v.toLongLong();
}
- if (!v2.canConvert(d.type) || !v2.convert(d.type))
+ if (!v2.canConvert(v1.d.type) || !v2.convert(v1.d.type))
return false;
}
- return handlerManager[d.type]->compare(&d, &v2.d);
+ if (v1.d.type >= QMetaType::User) {
+ int result;
+ if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(v1.d)), QT_PREPEND_NAMESPACE(constData(v2.d)), v1.d.type, &result))
+ return result == 0;
+ }
+ return handlerManager[v1.d.type]->compare(&v1.d, &v2.d);
+}
+
+/*!
+ \internal
+ */
+int QVariant::compare(const QVariant &v) const
+{
+ if (cmp(v))
+ return 0;
+ QVariant v1 = *this;
+ QVariant v2 = v;
+ if (v1.d.type != v2.d.type) {
+ // if both types differ, try to convert
+ if (v2.canConvert(v1.d.type)) {
+ QVariant temp = v2;
+ if (temp.convert(v1.d.type))
+ v2 = temp;
+ }
+ if (v1.d.type != v2.d.type && v1.canConvert(v2.d.type)) {
+ QVariant temp = v1;
+ if (temp.convert(v2.d.type))
+ v1 = temp;
+ }
+ if (v1.d.type != v2.d.type) {
+ // if conversion fails, default to toString
+ return v1.toString().compare(v2.toString(), Qt::CaseInsensitive);
+ }
+ }
+ if (v1.d.type >= QMetaType::User) {
+ int result;
+ if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v2.d)), d.type, &result))
+ return result;
+ }
+ if (qIsNumericType(v1.d.type)) {
+ if (qIsFloatingPoint(v1.d.type))
+ return v1.toReal() < v2.toReal() ? -1 : 1;
+ else
+ return v1.toLongLong() < v2.toLongLong() ? -1 : 1;
+ }
+ switch (v1.d.type) {
+ case QVariant::Date:
+ return v1.toDate() < v2.toDate() ? -1 : 1;
+ case QVariant::Time:
+ return v1.toTime() < v2.toTime() ? -1 : 1;
+ case QVariant::DateTime:
+ return v1.toDateTime() < v2.toDateTime() ? -1 : 1;
+ }
+ return v1.toString().compare(v2.toString(), Qt::CaseInsensitive);
}
/*!
@@ -3022,7 +3210,16 @@ QDebug operator<<(QDebug dbg, const QVariant &v)
dbg.nospace() << "QVariant(";
if (typeId != QMetaType::UnknownType) {
dbg.nospace() << QMetaType::typeName(typeId) << ", ";
- handlerManager[typeId]->debugStream(dbg, v);
+ bool userStream = false;
+ bool canConvertToString = false;
+ if (typeId >= QMetaType::User) {
+ userStream = QMetaType::debugStream(dbg, constData(v.d), typeId);
+ canConvertToString = v.canConvert<QString>();
+ }
+ if (!userStream && canConvertToString)
+ dbg << v.toString();
+ else if (!userStream)
+ handlerManager[typeId]->debugStream(dbg, v);
} else {
dbg.nospace() << "Invalid";
}
@@ -3074,7 +3271,12 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
returned. Note that this only works for QObject subclasses which use the
Q_OBJECT macro.
- \sa setValue(), fromValue(), canConvert()
+ If the QVariant contains a sequential container and \c{T} is QVariantList, the
+ elements of the container will be converted into QVariants and returned as a QVariantList.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ \sa setValue(), fromValue(), canConvert(), qRegisterSequentialConverter()
*/
/*! \fn bool QVariant::canConvert() const
@@ -3226,4 +3428,359 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
\internal
*/
+/*!
+ \class QSequentialIterable
+
+ \inmodule QtCore
+ \brief The QSequentialIterable class is an iterable interface for a container in a QVariant.
+
+ This class allows several methods of accessing the elements of a container held within
+ a QVariant. An instance of QSequentialIterable can be extracted from a QVariant if it can
+ be converted to a QVariantList.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ The container itself is not copied before iterating over it.
+
+ \sa QVariant
+*/
+
+/*! \fn QSequentialIterable::QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl)
+
+ \internal
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::begin() const
+
+ Returns a QSequentialIterable::const_iterator for the beginning of the container. This
+ can be used in stl-style iteration.
+
+ \sa end()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::end() const
+
+ Returns a QSequentialIterable::const_iterator for the end of the container. This
+ can be used in stl-style iteration.
+
+ \sa begin()
+*/
+
+/*! \fn QVariant QSequentialIterable::at(int idx) const
+
+ Returns the element at position \a idx in the container.
+*/
+
+/*! \fn int QSequentialIterable::size() const
+
+ Returns the number of elements in the container.
+*/
+
+/*! \fn bool QSequentialIterable::canReverseIterate() const
+
+ Returns whether it is possible to iterate over the container in reverse. This
+ corresponds to the std::bidirectional_iterator_tag iterator trait of the
+ const_iterator of the container.
+*/
+
+/*!
+ \class QSequentialIterable::const_iterator
+
+ \inmodule QtCore
+ \brief The QSequentialIterable::const_iterator allows iteration over a container in a QVariant.
+
+ A QSequentialIterable::const_iterator can only be created by a QSequentialIterable instance,
+ and can be used in a way similar to other stl-style iterators.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ \sa QSequentialIterable
+*/
+
+
+/*! \fn QSequentialIterable::const_iterator::~const_iterator()
+
+ Destroys the QSequentialIterable::const_iterator.
+*/
+
+/*! \fn QSequentialIterable::const_iterator::const_iterator(const const_iterator &other)
+
+ Creates a copy of \a other.
+*/
+
+/*! \fn QVariant QSequentialIterable::const_iterator::operator*() const
+
+ Returns the current item, converted to a QVariant.
+*/
+
+/*! \fn bool QSequentialIterable::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QSequentialIterable::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the container and returns an iterator to the new current
+ item.
+
+ Calling this function on QSequentialIterable::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the container and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QSequentialIterable::begin() leads to undefined results.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa operator++(), canReverseIterate()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa canReverseIterate()
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa operator+=(), operator-(), canReverseIterate()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator.
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa operator+(), operator-=(), canReverseIterate()
+*/
+
+/*!
+ \class QAssociativeIterable
+
+ \inmodule QtCore
+ \brief The QAssociativeIterable class is an iterable interface for an associative container in a QVariant.
+
+ This class allows several methods of accessing the elements of an associative container held within
+ a QVariant. An instance of QAssociativeIterable can be extracted from a QVariant if it can
+ be converted to a QVariantHash or QVariantMap.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ The container itself is not copied before iterating over it.
+
+ \sa QVariant
+*/
+
+/*! \fn QAssociativeIterable::QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl)
+
+ \internal
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::begin() const
+
+ Returns a QAssociativeIterable::const_iterator for the beginning of the container. This
+ can be used in stl-style iteration.
+
+ \sa end()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::end() const
+
+ Returns a QAssociativeIterable::const_iterator for the end of the container. This
+ can be used in stl-style iteration.
+
+ \sa begin()
+*/
+
+/*! \fn QVariant QAssociativeIterable::value(const QVariant &key) const
+
+ Returns the value for the given \a key in the container, if the types are convertible.
+*/
+
+/*! \fn int QAssociativeIterable::size() const
+
+ Returns the number of elements in the container.
+*/
+
+/*!
+ \class QAssociativeIterable::const_iterator
+
+ \inmodule QtCore
+ \brief The QAssociativeIterable::const_iterator allows iteration over a container in a QVariant.
+
+ A QAssociativeIterable::const_iterator can only be created by a QAssociativeIterable instance,
+ and can be used in a way similar to other stl-style iterators.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ \sa QAssociativeIterable
+*/
+
+
+/*! \fn QAssociativeIterable::const_iterator::~const_iterator()
+
+ Destroys the QAssociativeIterable::const_iterator.
+*/
+
+/*! \fn QAssociativeIterable::const_iterator::const_iterator(const const_iterator &other)
+
+ Creates a copy of \a other.
+*/
+
+/*! \fn QVariant QAssociativeIterable::const_iterator::operator*() const
+
+ Returns the current value, converted to a QVariant.
+*/
+
+/*! \fn QVariant QAssociativeIterable::const_iterator::key() const
+
+ Returns the current key, converted to a QVariant.
+*/
+
+/*! \fn QVariant QAssociativeIterable::const_iterator::value() const
+
+ Returns the current value, converted to a QVariant.
+*/
+
+/*! \fn bool QAssociativeIterable::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QAssociativeIterable::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the container and returns an iterator to the new current
+ item.
+
+ Calling this function on QAssociativeIterable::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the container and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QAssociativeIterable::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items.
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator.
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator.
+
+ \sa operator+(), operator-=()
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 6f212f5000..3345131c0f 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -49,6 +49,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
@@ -432,6 +433,14 @@ class Q_CORE_EXPORT QVariant
{ return cmp(v); }
inline bool operator!=(const QVariant &v) const
{ return !cmp(v); }
+ inline bool operator<(const QVariant &v) const
+ { return compare(v) < 0; }
+ inline bool operator<=(const QVariant &v) const
+ { return compare(v) <= 0; }
+ inline bool operator>(const QVariant &v) const
+ { return compare(v) > 0; }
+ inline bool operator>=(const QVariant &v) const
+ { return compare(v) >= 0; }
protected:
friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
@@ -449,6 +458,7 @@ public:
Private d;
void create(int type, const void *copy);
bool cmp(const QVariant &other) const;
+ int compare(const QVariant &other) const;
bool convert(const int t, void *ptr) const;
private:
@@ -562,6 +572,173 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
}
#endif
+class QSequentialIterable
+{
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+public:
+ struct const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QSequentialIterable;
+ inline explicit const_iterator(const QSequentialIterable &iter, QAtomicInt *ref_)
+ : m_impl(iter.m_impl), ref(ref_) { ref->ref(); }
+
+ inline explicit const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl &impl, QAtomicInt *ref_)
+ : m_impl(impl), ref(ref_) { ref->ref(); }
+
+ inline void begin() { m_impl.moveToBegin(); }
+ inline void end() { m_impl.moveToEnd(); }
+ public:
+ inline ~const_iterator() {
+ if (!ref->deref()) {
+ m_impl.destroyIter();
+ }
+ }
+
+ inline const_iterator(const const_iterator &other) : m_impl(other.m_impl), ref(other.ref) {
+ ref->ref();
+ }
+
+ inline const QVariant operator*() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrent();
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return QVariant(d.metaTypeId, d.data, d.flags);
+ }
+ inline bool operator==(const const_iterator &o) const { return m_impl.equal(o.m_impl); }
+ inline bool operator!=(const const_iterator &o) const { return !m_impl.equal(o.m_impl); }
+ inline const_iterator &operator++() { m_impl.advance(1); return *this; }
+ inline const_iterator operator++(int) { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; m_impl.advance(1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator--() { m_impl.advance(-1); return *this; }
+ inline const_iterator operator--(int) { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; m_impl.advance(-1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator+=(int j) { m_impl.advance(j); return *this; }
+ inline const_iterator &operator-=(int j) { m_impl.advance(-j); return *this; }
+ inline const_iterator operator+(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; impl.advance(j); return const_iterator(impl, this->ref); }
+ inline const_iterator operator-(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; impl.advance(-j); return const_iterator(impl, this->ref); }
+ };
+
+ friend struct const_iterator;
+
+ explicit QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl)
+ : m_impl(impl)
+ {
+ }
+
+ const_iterator begin() const { const_iterator it(*this, new QAtomicInt(0)); it.begin(); return it; }
+ const_iterator end() const { const_iterator it(*this, new QAtomicInt(0)); it.end(); return it; }
+
+ QVariant at(int idx) const {
+ const QtMetaTypePrivate::VariantData d = m_impl.at(idx);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return QVariant(d.metaTypeId, d.data, d.flags);
+ }
+ int size() const { return m_impl.size(); }
+
+ bool canReverseIterate() const
+ { return m_impl._iteratorCapabilities & QtMetaTypePrivate::BiDirectionalCapability; }
+};
+
+class QAssociativeIterable
+{
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+public:
+ struct const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QAssociativeIterable;
+ inline explicit const_iterator(const QAssociativeIterable &iter, QAtomicInt *ref_)
+ : m_impl(iter.m_impl), ref(ref_) { ref->ref(); }
+
+ inline explicit const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl &impl, QAtomicInt *ref_)
+ : m_impl(impl), ref(ref_) { ref->ref(); }
+
+ inline void begin() { m_impl.begin(); }
+ inline void end() { m_impl.end(); }
+ public:
+ inline ~const_iterator() {
+ if (!ref->deref()) {
+ m_impl.destroyIter();
+ }
+ }
+ inline const_iterator(const const_iterator &other) : m_impl(other.m_impl), ref(other.ref) {
+ ref->ref();
+ }
+
+ inline const QVariant key() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrentKey();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+
+ inline const QVariant value() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+
+ inline const QVariant operator*() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+ inline bool operator==(const const_iterator &o) const { return m_impl.equal(o.m_impl); }
+ inline bool operator!=(const const_iterator &o) const { return !m_impl.equal(o.m_impl); }
+ inline const_iterator &operator++() { m_impl.advance(1); return *this; }
+ inline const_iterator operator++(int) { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; m_impl.advance(1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator--() { m_impl.advance(-1); return *this; }
+ inline const_iterator operator--(int) { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; m_impl.advance(-1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator+=(int j) { m_impl.advance(j); return *this; }
+ inline const_iterator &operator-=(int j) { m_impl.advance(-j); return *this; }
+ inline const_iterator operator+(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; impl.advance(j); return const_iterator(impl, this->ref); }
+ inline const_iterator operator-(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; impl.advance(-j); return const_iterator(impl, this->ref); }
+ };
+
+ friend struct const_iterator;
+
+ explicit QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl)
+ : m_impl(impl)
+ {
+ }
+
+ const_iterator begin() const { const_iterator it(*this, new QAtomicInt(0)); it.begin(); return it; }
+ const_iterator end() const { const_iterator it(*this, new QAtomicInt(0)); it.end(); return it; }
+
+ QVariant value(const QVariant &key) const
+ {
+ QVariant key_ = key;
+ if (!key_.canConvert(m_impl._metaType_id_key))
+ return QVariant();
+ if (!key_.convert(m_impl._metaType_id_key))
+ return QVariant();
+ const QtMetaTypePrivate::VariantData dkey(key_.userType(), key_.constData(), 0 /*key.flags()*/);
+ QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl;
+ impl.find(dkey);
+ QtMetaTypePrivate::QAssociativeIterableImpl endIt = m_impl;
+ endIt.end();
+ if (impl.equal(endIt))
+ return QVariant();
+ const QtMetaTypePrivate::VariantData d = impl.getCurrentValue();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+
+ int size() const { return m_impl.size(); }
+};
+
+#ifndef QT_MOC
namespace QtPrivate {
template<typename T>
struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T>
@@ -571,26 +748,132 @@ namespace QtPrivate {
const int vid = qMetaTypeId<T>();
if (vid == v.userType())
return *reinterpret_cast<const T *>(v.constData());
- if (vid < int(QMetaType::User)) {
- T t;
- if (v.convert(vid, &t))
- return t;
- }
+ T t;
+ if (v.convert(vid, &t))
+ return t;
return T();
}
#ifndef QT_NO_QOBJECT
static T object(const QVariant &v)
{
- return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject ? v.d.data.o : 0);
+ return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject
+ ? v.d.data.o
+ : QVariantValueHelper::metaType(v));
}
#endif
};
+
+ template<typename T>
+ struct QVariantValueHelperInterface : QVariantValueHelper<T>
+ {
+ };
+
+ template<>
+ struct QVariantValueHelperInterface<QSequentialIterable>
+ {
+ static QSequentialIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QVariantList*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QStringList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QStringList*>(v.constData())));
+ }
+ return QSequentialIterable(v.value<QtMetaTypePrivate::QSequentialIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QAssociativeIterable>
+ {
+ static QAssociativeIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantMap>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantMap*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QVariantHash>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData())));
+ }
+ return QAssociativeIterable(v.value<QtMetaTypePrivate::QAssociativeIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantList>
+ {
+ static QVariantList invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QStringList>() || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
+ QVariantList l;
+ l.reserve(iter.size());
+ for (QSequentialIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l << *it;
+ return l;
+ }
+ return QVariantValueHelper<QVariantList>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantHash>
+ {
+ static QVariantHash invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantHash l;
+ l.reserve(iter.size());
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantHash>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantMap>
+ {
+ static QVariantMap invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantMap l;
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantMap>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QPair<QVariant, QVariant> >
+ {
+ static QPair<QVariant, QVariant> invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QPair<QVariant, QVariant> >())
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+
+ const QtMetaTypePrivate::VariantData d1 = pi.first();
+ QVariant v1(d1.metaTypeId, d1.data, d1.flags);
+ if (d1.metaTypeId == qMetaTypeId<QVariant>())
+ v1 = *reinterpret_cast<const QVariant*>(d1.data);
+
+ const QtMetaTypePrivate::VariantData d2 = pi.second();
+ QVariant v2(d2.metaTypeId, d2.data, d2.flags);
+ if (d2.metaTypeId == qMetaTypeId<QVariant>())
+ v2 = *reinterpret_cast<const QVariant*>(d2.data);
+
+ return QPair<QVariant, QVariant>(v1, v2);
+ }
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+ }
+ };
}
-#ifndef QT_MOC
template<typename T> inline T qvariant_cast(const QVariant &v)
{
- return QtPrivate::QVariantValueHelper<T>::invoke(v);
+ return QtPrivate::QVariantValueHelperInterface<T>::invoke(v);
}
template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index eb7a7f7fa8..338b3d0972 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -9,14 +9,16 @@ HEADERS += \
plugin/quuid.h \
plugin/qfactoryloader_p.h \
plugin/qsystemlibrary_p.h \
- plugin/qelfparser_p.h
+ plugin/qelfparser_p.h \
+ plugin/qmachparser_p.h
SOURCES += \
plugin/qpluginloader.cpp \
plugin/qfactoryloader.cpp \
plugin/quuid.cpp \
plugin/qlibrary.cpp \
- plugin/qelfparser_p.cpp
+ plugin/qelfparser_p.cpp \
+ plugin/qmachparser.cpp
win32 {
SOURCES += \
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 3c8e00519b..a3e809a266 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -235,13 +235,10 @@ QList<QJsonObject> QFactoryLoader::metaData() const
for (int i = 0; i < d->libraryList.size(); ++i)
metaData.append(d->libraryList.at(i)->metaData);
- QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
- for (int i = 0; i < staticPlugins.count(); ++i) {
- const char *rawMetaData = staticPlugins.at(i).metaData();
- QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
+ foreach (const QStaticPlugin &plugin, QPluginLoader::staticPlugins()) {
+ const QJsonObject object = plugin.metaData();
if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
continue;
-
metaData.append(object);
}
return metaData;
@@ -269,10 +266,9 @@ QObject *QFactoryLoader::instance(int index) const
}
index -= d->libraryList.size();
- QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
+ QVector<QStaticPlugin> staticPlugins = QPluginLoader::staticPlugins();
for (int i = 0; i < staticPlugins.count(); ++i) {
- const char *rawMetaData = staticPlugins.at(i).metaData();
- QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
+ const QJsonObject object = staticPlugins.at(i).metaData();
if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
continue;
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 3432f9619d..92e60c2216 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -1,7 +1,7 @@
-
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -64,6 +64,7 @@
#include <qjsondocument.h>
#include <qjsonvalue.h>
#include "qelfparser_p.h"
+#include "qmachparser_p.h"
QT_BEGIN_NAMESPACE
@@ -180,8 +181,6 @@ QT_BEGIN_NAMESPACE
*/
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
-
static long qt_find_pattern(const char *s, ulong s_len,
const char *pattern, ulong p_len)
{
@@ -228,7 +227,7 @@ static long qt_find_pattern(const char *s, ulong s_len,
information could not be read.
Returns true if version information is present and successfully read.
*/
-static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
+static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
{
QFile file(library);
if (!file.open(QIODevice::ReadOnly)) {
@@ -253,7 +252,7 @@ static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
}
/*
- ELF binaries on GNU, have .qplugin sections.
+ ELF and Mach-O binaries with GCC have .qplugin sections.
*/
bool hasMetaData = false;
long pos = 0;
@@ -274,6 +273,26 @@ static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
pos += rel;
hasMetaData = true;
}
+#elif defined (Q_OF_MACH_O)
+ {
+ QString errorString;
+ int r = QMachOParser::parse(filedata, fdlen, library, &errorString, &pos, &fdlen);
+ if (r == QMachOParser::NotSuitable) {
+ if (qt_debug_component())
+ qWarning("QMachOParser: %s", qPrintable(errorString));
+ if (lib)
+ lib->errorString = errorString;
+ return false;
+ }
+ // even if the metadata section was not found, the Mach-O parser will
+ // at least return the boundaries of the right architecture
+ long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
+ if (rel < 0)
+ pos = -1;
+ else
+ pos += rel;
+ hasMetaData = true;
+ }
#else
pos = qt_find_pattern(filedata, fdlen, pattern, plen);
if (pos > 0)
@@ -300,8 +319,6 @@ static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
return ret;
}
-#endif // Q_OS_UNIX && !Q_OS_MAC
-
static void installCoverageTool(QLibraryPrivate *libPrivate)
{
#ifdef __COVERAGESCANNER__
@@ -618,41 +635,18 @@ bool QLibrary::isLibrary(const QString &fileName)
}
-#if defined (Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_CC_INTEL)
-#define QT_USE_MS_STD_EXCEPTION 1
-const char* qt_try_versioninfo(void *pfn, bool *exceptionThrown)
-{
- *exceptionThrown = false;
- const char *szData = 0;
- typedef const char * (*VerificationFunction)();
- VerificationFunction func = reinterpret_cast<VerificationFunction>(pfn);
- __try {
- if(func)
- szData = func();
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- *exceptionThrown = true;
- }
- return szData;
-}
-#endif
-
typedef const char * (*QtPluginQueryVerificationDataFunction)();
-bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv, bool *exceptionThrown)
+static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv)
{
- *exceptionThrown = false;
const char *szData = 0;
if (!pfn)
return false;
-#ifdef QT_USE_MS_STD_EXCEPTION
- szData = qt_try_versioninfo((void *)pfn, exceptionThrown);
- if (*exceptionThrown)
- return false;
-#else
+
szData = pfn();
-#endif
if (!szData)
return false;
+
QJsonDocument doc = QLibraryPrivate::fromRawMetaData(szData);
if (doc.isNull())
return false;
@@ -690,80 +684,15 @@ void QLibraryPrivate::updatePluginState()
}
#endif
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
if (!pHnd) {
- // use unix shortcut to avoid loading the library
- success = qt_unix_query(fileName, this);
- } else
-#endif
- {
- bool retryLoadLibrary = false; // Only used on Windows with MS compiler.(false in other cases)
- do {
- bool temporary_load = false;
-#ifdef Q_OS_WIN
- HMODULE hTempModule = 0;
-#endif
- if (!pHnd) {
-#ifdef Q_OS_WIN
- DWORD dwFlags = (retryLoadLibrary) ? 0: DONT_RESOLVE_DLL_REFERENCES;
- //avoid 'Bad Image' message box
- UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
- hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, dwFlags);
- SetErrorMode(oldmode);
-#else
- temporary_load = load();
-#endif
- }
- QtPluginQueryVerificationDataFunction getMetaData = NULL;
-
- bool exceptionThrown = false;
- bool ret = false;
-#ifdef Q_OS_WIN
- if (hTempModule) {
- getMetaData = (QtPluginQueryVerificationDataFunction)
-#ifdef Q_OS_WINCE
- ::GetProcAddress(hTempModule, L"qt_plugin_query_metadata")
-#else
- ::GetProcAddress(hTempModule, "qt_plugin_query_metadata")
-#endif
- ;
- } else
-#endif
- {
- getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
- }
-
- if (getMetaData)
- ret = qt_get_metadata(getMetaData, this, &exceptionThrown);
-
- if (temporary_load)
- unload();
- if (!exceptionThrown) {
- if (ret) {
- success = true;
- }
- retryLoadLibrary = false;
- }
-#ifdef QT_USE_MS_STD_EXCEPTION
- else {
- // An exception was thrown when calling qt_plugin_query_verification_data().
- // This usually happens when plugin is compiled with the /clr compiler flag,
- // & will only work if the dependencies are loaded & DLLMain() is called.
- // LoadLibrary() will do this, try once with this & if it fails don't load.
- retryLoadLibrary = !retryLoadLibrary;
- }
-#endif
-#ifdef Q_OS_WIN
- if (hTempModule) {
- BOOL ok = ::FreeLibrary(hTempModule);
- if (ok) {
- hTempModule = 0;
- }
-
- }
-#endif
- } while (retryLoadLibrary); // Will be 'false' in all cases other than when an
- // exception is thrown(will happen only when using a MS compiler)
+ // scan for the plugin metadata without loading
+ success = findPatternUnloaded(fileName, this);
+ } else {
+ // library is already loaded (probably via QLibrary)
+ // simply get the target function and call it.
+ QtPluginQueryVerificationDataFunction getMetaData = NULL;
+ getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
+ success = qt_get_metadata(getMetaData, this);
}
if (!success) {
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index abf11be9f7..20b0c7e20f 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -98,9 +98,6 @@ public:
static QStringList suffixes_sys(const QString &fullVersion);
static QStringList prefixes_sys();
- static QVector<QStaticPlugin> staticPlugins();
-
-
QPointer<QObject> inst;
QtPluginInstanceFunction instance;
QJsonObject metaData;
diff --git a/src/corelib/plugin/qmachparser.cpp b/src/corelib/plugin/qmachparser.cpp
new file mode 100644
index 0000000000..5152a92d1d
--- /dev/null
+++ b/src/corelib/plugin/qmachparser.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmachparser_p.h"
+
+#if defined(Q_OF_MACH_O) && !defined(QT_NO_LIBRARY)
+
+#include <qendian.h>
+#include "qlibrary_p.h"
+
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_PROCESSOR_X86_64)
+# define MACHO64
+static const cpu_type_t my_cputype = CPU_TYPE_X86_64;
+#elif defined(Q_PROCESSOR_X86_32)
+static const cpu_type_t my_cputype = CPU_TYPE_X86;
+#elif defined(Q_PROCESSOR_POWER_64)
+# define MACHO64
+static const cpu_type_t my_cputype = CPU_TYPE_POWERPC64;
+#elif defined(Q_PROCESSOR_POWER_32)
+static const cpu_type_t my_cputype = CPU_TYPE_POWERPC;
+#elif defined(Q_PROCESSOR_ARM)
+static const cpu_type_t my_cputype = CPU_TYPE_ARM;
+#else
+# error "Unknown CPU type"
+#endif
+
+#ifdef MACHO64
+# undef MACHO64
+typedef mach_header_64 my_mach_header;
+typedef segment_command_64 my_segment_command;
+typedef section_64 my_section;
+static const uint32_t my_magic = MH_MAGIC_64;
+#else
+typedef mach_header my_mach_header;
+typedef segment_command my_segment_command;
+typedef section my_section;
+static const uint32_t my_magic = MH_MAGIC;
+#endif
+
+static int ns(const QString &reason, const QString &library, QString *errorString)
+{
+ if (errorString)
+ *errorString = QLibrary::tr("'%1' is not a valid Mach-O binary (%2)")
+ .arg(library, reason.isEmpty() ? QLibrary::tr("file is corrupt") : reason);
+ return QMachOParser::NotSuitable;
+}
+
+int QMachOParser::parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen)
+{
+ // The minimum size of a Mach-O binary we're interested in.
+ // It must have a full Mach header, at least one segment and at least one
+ // section. It's probably useless with just the "qtmetadata" section, but
+ // it's valid nonetheless.
+ // A fat binary must have this plus the fat header, of course.
+ static const size_t MinFileSize = sizeof(my_mach_header) + sizeof(my_segment_command) + sizeof(my_section);
+ static const size_t MinFatHeaderSize = sizeof(fat_header) + 2 * sizeof(fat_arch);
+
+ if (Q_UNLIKELY(fdlen < MinFileSize))
+ return ns(QLibrary::tr("file too small"), library, errorString);
+
+ // find out if this is a fat Mach-O binary first
+ const my_mach_header *header = 0;
+ const fat_header *fat = reinterpret_cast<const fat_header *>(m_s);
+ if (fat->magic == qToBigEndian(FAT_MAGIC)) {
+ // find our architecture in the binary
+ const fat_arch *arch = reinterpret_cast<const fat_arch *>(fat + 1);
+ if (Q_UNLIKELY(fdlen < MinFatHeaderSize)) {
+ return ns(QLibrary::tr("file too small"), library, errorString);
+ }
+
+ int count = qFromBigEndian(fat->nfat_arch);
+ if (Q_UNLIKELY(fdlen < sizeof(*fat) + sizeof(*arch) * count))
+ return ns(QString(), library, errorString);
+
+ for (int i = 0; i < count; ++i) {
+ if (arch[i].cputype == qToBigEndian(my_cputype)) {
+ // ### should we check the CPU subtype? Maybe on ARM?
+ uint32_t size = qFromBigEndian(arch[i].size);
+ uint32_t offset = qFromBigEndian(arch[i].offset);
+ if (Q_UNLIKELY(size > fdlen) || Q_UNLIKELY(offset > fdlen)
+ || Q_UNLIKELY(size + offset > fdlen) || Q_UNLIKELY(size < MinFileSize))
+ return ns(QString(), library, errorString);
+
+ header = reinterpret_cast<const my_mach_header *>(m_s + offset);
+ fdlen = size;
+ break;
+ }
+ }
+ if (!header)
+ return ns(QLibrary::tr("no suitable architecture in fat binary"), library, errorString);
+
+ // check the magic again
+ if (Q_UNLIKELY(header->magic != my_magic))
+ return ns(QString(), library, errorString);
+ } else {
+ header = reinterpret_cast<const my_mach_header *>(m_s);
+ fat = 0;
+
+ // check magic
+ if (header->magic != my_magic)
+ return ns(QLibrary::tr("invalid magic %1").arg(qFromBigEndian(header->magic), 8, 16, QLatin1Char('0')),
+ library, errorString);
+ }
+
+ // from this point on, fdlen is specific to this architecture
+ // from this point on, everything is in host byte order
+ *pos = reinterpret_cast<const char *>(header) - m_s;
+
+ // (re-)check the CPU type
+ // ### should we check the CPU subtype? Maybe on ARM?
+ if (header->cputype != my_cputype) {
+ if (fat)
+ return ns(QString(), library, errorString);
+ return ns(QLibrary::tr("wrong architecture"), library, errorString);
+ }
+
+ // check the file type
+ if (Q_UNLIKELY(header->filetype != MH_BUNDLE && header->filetype != MH_DYLIB))
+ return ns(QLibrary::tr("not a dynamic library"), library, errorString);
+
+ // find the __TEXT segment, "qtmetadata" section
+ const my_segment_command *seg = reinterpret_cast<const my_segment_command *>(header + 1);
+ ulong minsize = sizeof(*header);
+
+ for (uint i = 0; i < header->ncmds; ++i,
+ seg = reinterpret_cast<const my_segment_command *>(reinterpret_cast<const char *>(seg) + seg->cmdsize)) {
+ // We're sure that the file size includes at least one load command
+ // but we have to check anyway if we're past the first
+ if (Q_UNLIKELY(fdlen < minsize + sizeof(load_command)))
+ return ns(QString(), library, errorString);
+
+ // cmdsize can't be trusted until validated
+ // so check it against fdlen anyway
+ // (these are unsigned operations, with overflow behavior specified in the standard)
+ minsize += seg->cmdsize;
+ if (Q_UNLIKELY(fdlen < minsize) || Q_UNLIKELY(fdlen < seg->cmdsize))
+ return ns(QString(), library, errorString);
+
+ const uint32_t MyLoadCommand = sizeof(void *) > 4 ? LC_SEGMENT_64 : LC_SEGMENT;
+ if (seg->cmd != MyLoadCommand)
+ continue;
+
+ // is this the __TEXT segment?
+ if (strcmp(seg->segname, "__TEXT") == 0) {
+ const my_section *sect = reinterpret_cast<const my_section *>(seg + 1);
+ for (uint j = 0; j < seg->nsects; ++j) {
+ // is this the "qtmetadata" section?
+ if (strcmp(sect[j].sectname, "qtmetadata") != 0)
+ continue;
+
+ // found it!
+ if (Q_UNLIKELY(fdlen < sect[j].offset) || Q_UNLIKELY(fdlen < sect[j].size)
+ || Q_UNLIKELY(fdlen < sect[j].offset + sect[j].size))
+ return ns(QString(), library, errorString);
+
+ *pos += sect[j].offset;
+ *sectionlen = sect[j].size;
+ return QtMetaDataSection;
+ }
+ }
+
+ // other type of segment
+ seg = reinterpret_cast<const my_segment_command *>(reinterpret_cast<const char *>(seg) + seg->cmdsize);
+ }
+
+// // No Qt section was found, but at least we know that where the proper architecture's boundaries are
+// return NoQtSection;
+ if (errorString)
+ *errorString = QLibrary::tr("'%1' is not a Qt plugin").arg(library);
+ return NotSuitable;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/kms/qkmsudevlistener.h b/src/corelib/plugin/qmachparser_p.h
index 7534f0bcd3..6b2774dab6 100644
--- a/src/plugins/platforms/kms/qkmsudevlistener.h
+++ b/src/corelib/plugin/qmachparser_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,40 +39,41 @@
**
****************************************************************************/
-#ifndef QKMSUDEVLISTENER_H
-#define QKMSUDEVLISTENER_H
+#ifndef QMACHPARSER_P_H
+#define QMACHPARSER_P_H
-#include <QObject>
-#include <QMap>
-#include <QList>
-#include <QPointer>
-#include <QString>
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
-#include <qkmsudevhandler.h>
+#include <qendian.h>
+#include <qglobal.h>
-#include <libudev.h>
+#ifndef QT_NO_LIBRARY
+#if defined(Q_OF_MACH_O)
QT_BEGIN_NAMESPACE
-class QKmsUdevListener : public QObject
-{
- Q_OBJECT
+class QString;
+class QLibraryPrivate;
+class Q_AUTOTEST_EXPORT QMachOParser
+{
public:
- QKmsUdevListener(QObject *parent = 0);
- ~QKmsUdevListener();
-
- void addHandler(QKmsUdevHandler *);
-
-private:
- QList<QPointer<QKmsUdevHandler> > m_handlers;
- QMap<QString, QPointer<QObject> > m_devices;
- struct udev *m_udev;
-
- void scan();
- bool create(struct udev_device *);
+ enum { QtMetaDataSection, NoQtSection, NotSuitable };
+ static int parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen);
};
QT_END_NAMESPACE
-#endif // QKMSUDEVLISTENER_H
+#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
+#endif // QT_NO_LIBRARY
+
+#endif // QMACHPARSER_P_H
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index b91a0e9900..1ec9325e5e 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qjsonobject.h>
QT_BEGIN_NAMESPACE
@@ -59,11 +60,22 @@ QT_BEGIN_NAMESPACE
typedef QObject *(*QtPluginInstanceFunction)();
typedef const char *(*QtPluginMetaDataFunction)();
-struct QStaticPlugin
+struct Q_CORE_EXPORT QStaticPlugin
{
+ // Note: This struct is initialized using an initializer list.
+ // As such, it cannot have any new constructors or variables.
+#ifndef Q_QDOC
QtPluginInstanceFunction instance;
- QtPluginMetaDataFunction metaData;
+ QtPluginMetaDataFunction rawMetaData;
+#else
+ // Since qdoc gets confused by the use of function
+ // pointers, we add these dummes for it to parse instead:
+ QObject *instance();
+ const char *rawMetaData();
+#endif
+ QJsonObject metaData() const;
};
+Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 5a59942aad..ded4f6bfa2 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -107,6 +107,33 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \class QStaticPlugin
+ \inmodule QtCore
+ \since 5.2
+
+ \brief QStaticPlugin is a struct containing a reference to a
+ static plugin instance together with its meta data.
+
+ \sa QPluginLoader, {How to Create Qt Plugins}
+*/
+
+/*!
+ \fn QObject *QStaticPlugin::instance()
+
+ Returns the plugin instance.
+
+ \sa QPluginLoader::staticInstances()
+*/
+
+/*!
+ \fn const char *QStaticPlugin::rawMetaData()
+
+ Returns the raw meta data for the plugin.
+
+ \sa metaData(), Q_PLUGIN_METADATA()
+*/
+
+/*!
Constructs a plugin loader with the given \a parent.
*/
QPluginLoader::QPluginLoader(QObject *parent)
@@ -251,6 +278,7 @@ bool QPluginLoader::isLoaded() const
return d && d->pHnd && d->instance;
}
+#if defined(QT_SHARED)
static QString locatePlugin(const QString& fileName)
{
QStringList prefixes = QLibraryPrivate::prefixes_sys();
@@ -282,6 +310,7 @@ static QString locatePlugin(const QString& fileName)
qDebug() << fileName << "not found";
return QString();
}
+#endif
/*!
\property QPluginLoader::fileName
@@ -407,6 +436,7 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin plugin)
/*!
Returns a list of static plugin instances (root components) held
by the plugin loader.
+ \sa staticPlugins()
*/
QObjectList QPluginLoader::staticInstances()
{
@@ -419,8 +449,14 @@ QObjectList QPluginLoader::staticInstances()
return instances;
}
-
-QVector<QStaticPlugin> QLibraryPrivate::staticPlugins()
+/*!
+ Returns a list of QStaticPlugins held by the plugin
+ loader. The function is similar to \l staticInstances()
+ with the addition that a QStaticPlugin also contains
+ meta data information.
+ \sa staticInstances()
+*/
+QVector<QStaticPlugin> QPluginLoader::staticPlugins()
{
StaticPluginList *plugins = staticPluginList();
if (plugins)
@@ -428,6 +464,16 @@ QVector<QStaticPlugin> QLibraryPrivate::staticPlugins()
return QVector<QStaticPlugin>();
}
+/*!
+ Returns a the meta data for the plugin as a QJsonObject.
+
+ \sa rawMetaData()
+*/
+QJsonObject QStaticPlugin::metaData() const
+{
+ return QLibraryPrivate::fromRawMetaData(rawMetaData()).object();
+}
+
QT_END_NAMESPACE
#endif // QT_NO_LIBRARY
diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h
index 8f8833e839..88c8ba4fa0 100644
--- a/src/corelib/plugin/qpluginloader.h
+++ b/src/corelib/plugin/qpluginloader.h
@@ -43,6 +43,7 @@
#define QPLUGINLOADER_H
#include <QtCore/qlibrary.h>
+#include <QtCore/qplugin.h>
#ifndef QT_NO_LIBRARY
@@ -65,6 +66,7 @@ public:
QJsonObject metaData() const;
static QObjectList staticInstances();
+ static QVector<QStaticPlugin> staticPlugins();
bool load();
bool unload();
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index 24d89030d1..18aedfbf75 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -54,21 +54,6 @@
#include <errno.h>
#include <asm/unistd.h>
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
-// C++11 mode
-# include <type_traits>
-
-static void checkElapsedTimerIsTrivial()
-{
- Q_STATIC_ASSERT(std::has_trivial_default_constructor<QT_PREPEND_NAMESPACE(QElapsedTimer)>::value);
-}
-
-#else
-static void checkElapsedTimerIsTrivial()
-{
-}
-#endif
-
#ifndef QT_LINUX_FUTEX
# error "Qt build is broken: qmutex_linux.cpp is being built but futex support is not wanted"
#endif
@@ -175,7 +160,7 @@ static inline QMutexData *dummyFutexValue()
}
template <bool IsTimed> static inline
-bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -1) Q_DECL_NOTHROW
+bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -1, QElapsedTimer *elapsedTimer = 0) Q_DECL_NOTHROW
{
if (!IsTimed)
timeout = -1;
@@ -185,12 +170,9 @@ bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -
return false;
struct timespec ts, *pts = 0;
- QElapsedTimer elapsedTimer;
- checkElapsedTimerIsTrivial();
if (IsTimed && timeout > 0) {
ts.tv_sec = timeout / 1000;
ts.tv_nsec = (timeout % 1000) * 1000 * 1000;
- elapsedTimer.start();
}
// the mutex is locked already, set a bit indicating we're waiting
@@ -198,7 +180,7 @@ bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -
if (IsTimed && pts == &ts) {
// recalculate the timeout
qint64 xtimeout = qint64(timeout) * 1000 * 1000;
- xtimeout -= elapsedTimer.nsecsElapsed();
+ xtimeout -= elapsedTimer->nsecsElapsed();
if (xtimeout <= 0) {
// timer expired after we returned
return false;
@@ -232,7 +214,9 @@ void QBasicMutex::lockInternal() Q_DECL_NOTHROW
bool QBasicMutex::lockInternal(int timeout) Q_DECL_NOTHROW
{
Q_ASSERT(!isRecursive());
- return lockInternal_helper<true>(d_ptr, timeout);
+ QElapsedTimer elapsedTimer;
+ elapsedTimer.start();
+ return lockInternal_helper<true>(d_ptr, timeout, &elapsedTimer);
}
void QBasicMutex::unlockInternal() Q_DECL_NOTHROW
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 4d5bee3154..35d57b3d83 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -146,7 +146,8 @@ void QAdoptedThread::run()
QThreadPrivate::QThreadPrivate(QThreadData *d)
: QObjectPrivate(), running(false), finished(false),
- isInFinish(false), exited(false), returnCode(-1),
+ isInFinish(false), interruptionRequested(false),
+ exited(false), returnCode(-1),
stackSize(0), priority(QThread::InheritPriority), data(d)
{
#if defined (Q_OS_UNIX)
@@ -801,4 +802,61 @@ bool QThread::event(QEvent *event)
}
}
+/*!
+ \since 5.2
+
+ Request the interruption of the thread.
+ That request is advisory and it is up to code running on the thread to decide
+ if and how it should act upon such request.
+ This function does not stop any event loop running on the thread and
+ does not terminate it in any way.
+
+ \sa isInterruptionRequested()
+*/
+
+void QThread::requestInterruption()
+{
+ Q_D(QThread);
+ QMutexLocker locker(&d->mutex);
+ if (!d->running || d->finished || d->isInFinish)
+ return;
+ if (this == QCoreApplicationPrivate::theMainThread) {
+ qWarning("QThread::requestInterruption has no effect on the main thread");
+ return;
+ }
+ d->interruptionRequested = true;
+}
+
+/*!
+ \since 5.2
+
+ Return true if the task running on this thread should be stopped.
+ An interruption can be requested by requestInterruption().
+
+ This function can be used to make long running tasks cleanly interruptible.
+ Never checking or acting on the value returned by this function is safe,
+ however it is advisable do so regularly in long running functions.
+ Take care not to call it too often, to keep the overhead low.
+
+ \code
+ void long_task() {
+ forever {
+ if ( QThread::currentThread()->isInterruptionRequested() ) {
+ return;
+ }
+ }
+ }
+ \endcode
+
+ \sa currentThread() requestInterruption()
+*/
+bool QThread::isInterruptionRequested() const
+{
+ Q_D(const QThread);
+ QMutexLocker locker(&d->mutex);
+ if (!d->running || d->finished || d->isInFinish)
+ return false;
+ return d->interruptionRequested;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 19c0f82d86..f06981c0bd 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -86,6 +86,9 @@ public:
bool isFinished() const;
bool isRunning() const;
+ void requestInterruption();
+ bool isInterruptionRequested() const;
+
void setStackSize(uint stackSize);
uint stackSize() const;
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 9d773b3c1c..5e4eedaac7 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -150,6 +150,7 @@ public:
bool running;
bool finished;
bool isInFinish; //when in QThreadPrivate::finish
+ bool interruptionRequested;
bool exited;
int returnCode;
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 6a91193785..15558cb148 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -377,6 +377,7 @@ void QThreadPrivate::finish(void *arg)
d->thread_id = 0;
d->running = false;
d->finished = true;
+ d->interruptionRequested = false;
d->isInFinish = false;
d->thread_done.wakeAll();
@@ -549,6 +550,7 @@ void QThread::start(Priority priority)
d->finished = false;
d->returnCode = 0;
d->exited = false;
+ d->interruptionRequested = false;
pthread_attr_t attr;
pthread_attr_init(&attr);
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index a0fac8eff2..d49a6a9a8e 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -377,6 +377,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway)
d->running = false;
d->finished = true;
d->isInFinish = false;
+ d->interruptionRequested = false;
if (!d->waiters) {
CloseHandle(d->handle);
@@ -446,6 +447,7 @@ void QThread::start(Priority priority)
d->finished = false;
d->exited = false;
d->returnCode = 0;
+ d->interruptionRequested = false;
/*
NOTE: we create the thread in the suspended state, set the
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index a7d52f9652..9ef40a5209 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -52,14 +52,14 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QThreadPool, theInstance)
/*
- QThread wrapper, provides synchronizitaion against a ThreadPool
+ QThread wrapper, provides synchronization against a ThreadPool
*/
class QThreadPoolThread : public QThread
{
public:
QThreadPoolThread(QThreadPoolPrivate *manager);
void run();
- void registerTheadInactive();
+ void registerThreadInactive();
QThreadPoolPrivate *manager;
QRunnable *runnable;
@@ -103,7 +103,7 @@ void QThreadPoolThread::run()
qWarning("Qt Concurrent has caught an exception thrown from a worker thread.\n"
"This is not supported, exceptions thrown in worker threads must be\n"
"caught before control returns to Qt Concurrent.");
- registerTheadInactive();
+ registerThreadInactive();
throw;
}
#endif
@@ -121,7 +121,7 @@ void QThreadPoolThread::run()
} while (r != 0);
if (manager->isExiting) {
- registerTheadInactive();
+ registerThreadInactive();
break;
}
@@ -129,7 +129,7 @@ void QThreadPoolThread::run()
bool expired = manager->tooManyThreadsActive();
if (!expired) {
++manager->waitingThreads;
- registerTheadInactive();
+ registerThreadInactive();
// wait for work, exiting after the expiry timeout is reached
expired = !manager->runnableReady.wait(locker.mutex(), manager->expiryTimeout);
++manager->activeThreads;
@@ -139,13 +139,13 @@ void QThreadPoolThread::run()
}
if (expired) {
manager->expiredThreads.enqueue(this);
- registerTheadInactive();
+ registerThreadInactive();
break;
}
}
}
-void QThreadPoolThread::registerTheadInactive()
+void QThreadPoolThread::registerThreadInactive()
{
if (--manager->activeThreads == 0)
manager->noActiveThreads.wakeAll();
@@ -180,6 +180,7 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
// recycle an available thread
--waitingThreads;
enqueueTask(task);
+ runnableReady.wakeOne();
return true;
}
@@ -218,13 +219,10 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
if (it != begin && priority > (*(it - 1)).second)
it = std::upper_bound(begin, --it, priority);
queue.insert(it - begin, qMakePair(runnable, priority));
- runnableReady.wakeOne();
}
int QThreadPoolPrivate::activeThreadCount() const
{
- // To improve scalability this function is called without holding
- // the mutex lock -- keep it thread-safe.
return (allThreads.count()
- expiredThreads.count()
- waitingThreads
@@ -262,7 +260,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable)
/*!
\internal
- Makes all threads exit, waits for each tread to exit and deletes it.
+ Makes all threads exit, waits for each thread to exit and deletes it.
*/
void QThreadPoolPrivate::reset()
{
@@ -308,10 +306,22 @@ bool QThreadPoolPrivate::waitForDone(int msecs)
return queue.isEmpty() && activeThreads == 0;
}
+void QThreadPoolPrivate::clear()
+{
+ QMutexLocker locker(&mutex);
+ for (QList<QPair<QRunnable *, int> >::const_iterator it = queue.constBegin();
+ it != queue.constEnd(); ++it) {
+ QRunnable* r = it->first;
+ if (r->autoDelete() && !--r->ref)
+ delete r;
+ }
+ queue.clear();
+}
+
/*!
\internal
- Seaches for \a runnable in the queue, removes it from the queue and
- runs it if found. This functon does not return until the runnable
+ Searches for \a runnable in the queue, removes it from the queue and
+ runs it if found. This function does not return until the runnable
has completed.
*/
void QThreadPoolPrivate::stealRunnable(QRunnable *runnable)
@@ -446,8 +456,14 @@ void QThreadPool::start(QRunnable *runnable, int priority)
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
- if (!d->tryStart(runnable))
+ if (!d->tryStart(runnable)) {
d->enqueueTask(runnable, priority);
+
+ if (d->waitingThreads > 0) {
+ --d->waitingThreads;
+ d->runnableReady.wakeOne();
+ }
+ }
}
/*!
@@ -473,12 +489,11 @@ bool QThreadPool::tryStart(QRunnable *runnable)
Q_D(QThreadPool);
- // To improve scalability perform a check on the thread count
- // before locking the mutex.
+ QMutexLocker locker(&d->mutex);
+
if (d->allThreads.isEmpty() == false && d->activeThreadCount() >= d->maxThreadCount)
return false;
- QMutexLocker locker(&d->mutex);
return d->tryStart(runnable);
}
@@ -552,6 +567,7 @@ void QThreadPool::setMaxThreadCount(int maxThreadCount)
int QThreadPool::activeThreadCount() const
{
Q_D(const QThreadPool);
+ QMutexLocker locker(&d->mutex);
return d->activeThreadCount();
}
@@ -609,6 +625,21 @@ bool QThreadPool::waitForDone(int msecs)
return rc;
}
+/*!
+ \since 5.2
+
+ Removes the runnables that are not yet started from the queue.
+ The runnables for which \l{QRunnable::autoDelete()}{runnable->autoDelete()}
+ returns true are deleted.
+
+ \sa start()
+*/
+void QThreadPool::clear()
+{
+ Q_D(QThreadPool);
+ d->clear();
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
index ffc16dedbe..22a42c2272 100644
--- a/src/corelib/thread/qthreadpool.h
+++ b/src/corelib/thread/qthreadpool.h
@@ -83,6 +83,8 @@ public:
void releaseThread();
bool waitForDone(int msecs = -1);
+
+ void clear();
};
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index 754d754e74..ba77f7e57c 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -83,6 +83,7 @@ public:
void startThread(QRunnable *runnable = 0);
void reset();
bool waitForDone(int msecs);
+ void clear();
void stealRunnable(QRunnable *);
mutable QMutex mutex;
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 616a4bdfb8..e8322959ca 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -136,7 +136,7 @@ public:
code = pthread_cond_wait(&cond, &mutex);
}
if (code == 0 && wakeups == 0) {
- // many vendors warn of spurios wakeups from
+ // many vendors warn of spurious wakeups from
// pthread_cond_wait(), especially after signal delivery,
// even though POSIX doesn't allow for it... sigh
continue;
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index e3b76886f1..3bd3812e78 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -43,6 +43,7 @@
#define QALGORITHMS_H
#include <QtCore/qglobal.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -292,7 +293,7 @@ template <typename RandomAccessIterator, typename T>
Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
- RandomAccessIterator it = qLowerBound(begin, end, value);
+ RandomAccessIterator it = std::lower_bound(begin, end, value);
if (it == end || value < *it)
return end;
@@ -506,7 +507,7 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator
template <typename RandomAccessIterator, typename T, typename LessThan>
Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
- RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
+ RandomAccessIterator it = std::lower_bound(begin, end, value, lessThan);
if (it == end || lessThan(value, *it))
return end;
@@ -516,6 +517,73 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator
} //namespace QAlgorithmsPrivate
+
+// Use __builtin_popcount on gcc. Clang claims to be gcc
+// but has a bug where __builtin_popcount is not marked as
+// constexpr.
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#define QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint32 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint8 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint16 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint64 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcountll(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 36) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 48) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 60) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigned int v)
+{
+ return qPopulationCount(static_cast<quint64>(v));
+}
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#undef QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+
QT_END_NAMESPACE
#endif // QALGORITHMS_H
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index ad6c3d913c..f3dfddec77 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -635,3 +635,34 @@ of \a value in the variable passed as a reference in argument \a n.
\sa {qLess()}{qLess<T>()}
*/
+
+
+/*!
+ \fn uint qPopulationCount(quint8 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+
+ Returns the number of bits set in \a v. This number also called
+ the Hamming Weight of \a v.
+ */
+
+/*!
+ \fn uint qPopulationCount(quint16 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+ \overload
+ */
+
+/*!
+ \fn uint qPopulationCount(quint32 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+ \overload
+ */
+
+/*!
+ \fn uint qPopulationCount(quint64 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+ \overload
+ */
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
index b04c4f9c3d..fb60534495 100644
--- a/src/corelib/tools/qbitarray.cpp
+++ b/src/corelib/tools/qbitarray.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qbitarray.h"
+#include <qalgorithms.h>
#include <qdatastream.h>
#include <qdebug.h>
#include <string.h>
@@ -116,20 +117,33 @@ QT_BEGIN_NAMESPACE
\sa isEmpty()
*/
+/*
+ * QBitArray construction note:
+ *
+ * We overallocate the byte array by 1 byte. The first user bit is at
+ * d.data()[1]. On the extra first byte, we store the difference between the
+ * number of bits in the byte array (including this byte) and the number of
+ * bits in the bit array. Therefore, it's always a number between 8 and 15.
+ *
+ * This allows for fast calculation of the bit array size:
+ * inline int size() const { return (d.size() << 3) - *d.constData(); }
+ *
+ * Note: for an array of zero size, *d.constData() is the QByteArray implicit NUL.
+ */
+
/*!
Constructs a bit array containing \a size bits. The bits are
initialized with \a value, which defaults to false (0).
*/
QBitArray::QBitArray(int size, bool value)
+ : d(size <= 0 ? 0 : 1 + (size + 7)/8, Qt::Uninitialized)
{
Q_ASSERT_X(size >= 0, "QBitArray::QBitArray", "Size must be greater than or equal to 0.");
- if (size <= 0) {
- d.resize(0);
+ if (size <= 0)
return;
- }
- d.resize(1 + (size+7)/8);
+
uchar* c = reinterpret_cast<uchar*>(d.data());
- memset(c, value ? 0xff : 0, d.size());
+ memset(c + 1, value ? 0xff : 0, d.size() - 1);
*c = d.size()*8 - size;
if (value && size && size % 8)
*(c+1+size/8) &= (1 << (size%8)) - 1;
@@ -160,29 +174,23 @@ int QBitArray::count(bool on) const
for (int i = 0; i < len; ++i)
numBits += testBit(i);
#else
- // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
const quint8 *bits = reinterpret_cast<const quint8 *>(d.data()) + 1;
while (len >= 32) {
quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16) | (quint32(bits[3]) << 24);
- quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
- c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
- c += ((v >> 24) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
len -= 32;
bits += 4;
- numBits += int(c);
+ numBits += int(qPopulationCount(v));
}
while (len >= 24) {
quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16);
- quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
- c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
len -= 24;
bits += 3;
- numBits += int(c);
+ numBits += int(qPopulationCount(v));
}
- while (len >= 0) {
- if (bits[len / 8] & (1 << ((len - 1) & 7)))
- ++numBits;
+ while (len > 0) {
--len;
+ if (bits[len / 8] & (1 << (len & 7)))
+ ++numBits;
}
#endif
return on ? numBits : size() - numBits;
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
index 1103712627..eaf9b2ff25 100644
--- a/src/corelib/tools/qbitarray.h
+++ b/src/corelib/tools/qbitarray.h
@@ -61,6 +61,7 @@ public:
QBitArray(const QBitArray &other) : d(other.d) {}
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QBitArray(QBitArray &&other) : d(std::move(other.d)) {}
inline QBitArray &operator=(QBitArray &&other)
{ qSwap(d, other.d); return *this; }
#endif
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 6ce17e5e13..a2d3891f00 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -556,6 +556,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
d.take(); // realloc was successful
d.reset(p);
d->offset = sizeof(QByteArrayData);
+ d->size = 0; // Shut up valgrind "uninitialized variable" warning
int res = ::uncompress((uchar*)d->data(), &len,
(uchar*)data+4, nbytes-4);
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 9ab7155c2d..dbd8a81b92 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -1884,4 +1884,65 @@ static void canonicalOrderHelper(QString *str, QChar::UnicodeVersion version, in
}
}
+// returns true if the text is in a desired Normalization Form already; false otherwise.
+// sets lastStable to the position of the last stable code point
+static bool normalizationQuickCheckHelper(QString *str, QString::NormalizationForm mode, int from, int *lastStable)
+{
+ Q_STATIC_ASSERT(QString::NormalizationForm_D == 0);
+ Q_STATIC_ASSERT(QString::NormalizationForm_C == 1);
+ Q_STATIC_ASSERT(QString::NormalizationForm_KD == 2);
+ Q_STATIC_ASSERT(QString::NormalizationForm_KC == 3);
+
+ enum { NFQC_YES = 0, NFQC_NO = 1, NFQC_MAYBE = 3 };
+
+ const ushort *string = reinterpret_cast<const ushort *>(str->constData());
+ int length = str->length();
+
+ // this avoids one out of bounds check in the loop
+ while (length > from && QChar::isHighSurrogate(string[length - 1]))
+ --length;
+
+ uchar lastCombining = 0;
+ for (int i = from; i < length; ++i) {
+ int pos = i;
+ uint uc = string[i];
+ if (uc < 0x80) {
+ // ASCII characters are stable code points
+ lastCombining = 0;
+ *lastStable = pos;
+ continue;
+ }
+
+ if (QChar::isHighSurrogate(uc)) {
+ ushort low = string[i + 1];
+ if (!QChar::isLowSurrogate(low)) {
+ // treat surrogate like stable code point
+ lastCombining = 0;
+ *lastStable = pos;
+ continue;
+ }
+ ++i;
+ uc = QChar::surrogateToUcs4(uc, low);
+ }
+
+ const QUnicodeTables::Properties *p = qGetProp(uc);
+
+ if (p->combiningClass < lastCombining && p->combiningClass > 0)
+ return false;
+
+ const uchar check = (p->nfQuickCheck >> (mode << 1)) & 0x03;
+ if (check != NFQC_YES)
+ return false; // ### can we quick check NFQC_MAYBE ?
+
+ lastCombining = p->combiningClass;
+ if (lastCombining == 0)
+ *lastStable = pos;
+ }
+
+ if (length != str->length()) // low surrogate parts at the end of text
+ *lastStable = str->length() - 1;
+
+ return true;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp
new file mode 100644
index 0000000000..4f9e166587
--- /dev/null
+++ b/src/corelib/tools/qcommandlineoption.cpp
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
+** Copyright (C) 2013 David Faure <faure@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommandlineoption.h"
+
+#include "qset.h"
+
+QT_BEGIN_NAMESPACE
+
+class QCommandLineOptionPrivate : public QSharedData
+{
+public:
+ inline QCommandLineOptionPrivate()
+ { }
+
+ void setNames(const QStringList &nameList);
+
+ //! The list of names used for this option.
+ QStringList names;
+
+ //! The documentation name for the value, if one is expected
+ //! Example: "-o <file>" means valueName == "file"
+ QString valueName;
+
+ //! The description used for this option.
+ QString description;
+
+ //! The list of default values used for this option.
+ QStringList defaultValues;
+};
+
+/*!
+ \since 5.2
+ \class QCommandLineOption
+ \brief The QCommandLineOption class defines a possible command-line option.
+ \inmodule QtCore
+ \ingroup shared
+ \ingroup tools
+
+ This class is used to describe an option on the command line. It allows
+ different ways of defining the same option with multiple aliases possible.
+ It is also used to describe how the option is used - it may be a flag (e.g. \c{-v})
+ or take an argument (e.g. \c{-o file}).
+
+ Examples:
+ \snippet code/src_corelib_tools_qcommandlineoption.cpp 0
+
+ \sa QCommandLineParser
+*/
+
+/*!
+ Constructs a command line option object with the given arguments.
+
+ The name of the option is set to \a name.
+ The name can be either short or long. If the name is one character in
+ length, it is considered a short name. Option names must not be empty,
+ must not start with a dash or a slash character, must not contain a \c{=}
+ and cannot be repeated.
+
+ The description is set to \a description. It is customary to add a "."
+ at the end of the description.
+
+ In addition, the \a valueName can be set if the option expects a value.
+ The default value for the option is set to \a defaultValue.
+
+ \sa setDescription(), setValueName(), setDefaultValues()
+*/
+QCommandLineOption::QCommandLineOption(const QString &name, const QString &description,
+ const QString &valueName,
+ const QString &defaultValue)
+ : d(new QCommandLineOptionPrivate)
+{
+ d->setNames(QStringList(name));
+ setValueName(valueName);
+ setDescription(description);
+ setDefaultValue(defaultValue);
+}
+
+/*!
+ Constructs a command line option object with the given arguments.
+
+ This overload allows to set multiple names for the option, for instance
+ \c{o} and \c{output}.
+
+ The names of the option are set to \a names.
+ The names can be either short or long. Any name in the list that is one
+ character in length is a short name. Option names must not be empty,
+ must not start with a dash or a slash character, must not contain a \c{=}
+ and cannot be repeated.
+
+ The description is set to \a description. It is customary to add a "."
+ at the end of the description.
+
+ In addition, the \a valueName can be set if the option expects a value.
+ The default value for the option is set to \a defaultValue.
+
+ \sa setDescription(), setValueName(), setDefaultValues()
+*/
+QCommandLineOption::QCommandLineOption(const QStringList &names, const QString &description,
+ const QString &valueName,
+ const QString &defaultValue)
+ : d(new QCommandLineOptionPrivate)
+{
+ d->setNames(names);
+ setValueName(valueName);
+ setDescription(description);
+ setDefaultValue(defaultValue);
+}
+
+/*!
+ Constructs a QCommandLineOption object that is a copy of the QCommandLineOption
+ object \a other.
+
+ \sa operator=()
+*/
+QCommandLineOption::QCommandLineOption(const QCommandLineOption &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Destroys the command line option object.
+*/
+QCommandLineOption::~QCommandLineOption()
+{
+}
+
+/*!
+ Makes a copy of the \a other object and assigns it to this QCommandLineOption
+ object.
+*/
+QCommandLineOption &QCommandLineOption::operator=(const QCommandLineOption &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn void QCommandLineOption::swap(QCommandLineOption &other)
+
+ Swaps option \a other with this option. This operation is very
+ fast and never fails.
+*/
+
+/*!
+ Returns the names set for this option.
+ */
+QStringList QCommandLineOption::names() const
+{
+ return d->names;
+}
+
+void QCommandLineOptionPrivate::setNames(const QStringList &nameList)
+{
+ names.clear();
+ if (nameList.isEmpty())
+ qWarning("Options must have at least one name");
+ foreach (const QString &name, nameList) {
+ if (name.isEmpty())
+ qWarning("Option names cannot be empty");
+ else if (name.startsWith(QLatin1Char('-')))
+ qWarning("Option names cannot start with a '-'");
+ else if (name.startsWith(QLatin1Char('/')))
+ qWarning("Option names cannot start with a '/'");
+ else if (name.contains(QLatin1Char('=')))
+ qWarning("Option names cannot contain a '='");
+ else
+ names.append(name);
+ }
+}
+
+/*!
+ Sets the name of the expected value, for the documentation, to \a valueName.
+
+ Options without a value assigned have a boolean-like behavior:
+ either the user specifies --option or they don't.
+
+ Options with a value assigned need to set a name for the expected value,
+ for the documentation of the option in the help output. An option with names \c{o} and \c{output},
+ and a value name of \c{file} will appear as \c{-o, --output <file>}.
+
+ Call QCommandLineParser::argument() if you expect the option to be present
+ only once, and QCommandLineParser::arguments() if you expect that option
+ to be present multiple times.
+
+ \sa valueName()
+ */
+void QCommandLineOption::setValueName(const QString &valueName)
+{
+ d->valueName = valueName;
+}
+
+/*!
+ Returns the name of the expected value.
+
+ If empty, the option doesn't take a value.
+
+ \sa setValueName()
+ */
+QString QCommandLineOption::valueName() const
+{
+ return d->valueName;
+}
+
+/*!
+ Sets the description used for this option to \a description.
+
+ It is customary to add a "." at the end of the description.
+
+ The description is used by QCommandLineParser::showHelp().
+
+ \sa description()
+ */
+void QCommandLineOption::setDescription(const QString &description)
+{
+ d->description = description;
+}
+
+/*!
+ Returns the description set for this option.
+
+ \sa setDescription()
+ */
+QString QCommandLineOption::description() const
+{
+ return d->description;
+}
+
+/*!
+ Sets the default value used for this option to \a defaultValue.
+
+ The default value is used if the user of the application does not specify
+ the option on the command line.
+
+ If \a defaultValue is empty, the option has no default values.
+
+ \sa defaultValues() setDefaultValues()
+ */
+void QCommandLineOption::setDefaultValue(const QString &defaultValue)
+{
+ d->defaultValues.clear();
+ if (!defaultValue.isEmpty())
+ d->defaultValues << defaultValue;
+}
+
+/*!
+ Sets the list of default values used for this option to \a defaultValues.
+
+ The default values are used if the user of the application does not specify
+ the option on the command line.
+
+ \sa defaultValues() setDefaultValue()
+ */
+void QCommandLineOption::setDefaultValues(const QStringList &defaultValues)
+{
+ d->defaultValues = defaultValues;
+}
+
+/*!
+ Returns the default values set for this option.
+
+ \sa setDefaultValues()
+ */
+QStringList QCommandLineOption::defaultValues() const
+{
+ return d->defaultValues;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qcommandlineoption.h b/src/corelib/tools/qcommandlineoption.h
new file mode 100644
index 0000000000..7775aae5b6
--- /dev/null
+++ b/src/corelib/tools/qcommandlineoption.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMMANDLINEOPTION_H
+#define QCOMMANDLINEOPTION_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCommandLineOptionPrivate;
+
+class Q_CORE_EXPORT QCommandLineOption
+{
+public:
+ explicit QCommandLineOption(const QString &name, const QString &description = QString(),
+ const QString &valueName = QString(),
+ const QString &defaultValue = QString());
+ explicit QCommandLineOption(const QStringList &names, const QString &description = QString(),
+ const QString &valueName = QString(),
+ const QString &defaultValue = QString());
+ QCommandLineOption(const QCommandLineOption &other);
+
+ ~QCommandLineOption();
+
+ QCommandLineOption &operator=(const QCommandLineOption &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QCommandLineOption &operator=(QCommandLineOption &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
+
+ inline void swap(QCommandLineOption &other)
+ { qSwap(d, other.d); }
+
+ QStringList names() const;
+
+ void setValueName(const QString &name);
+ QString valueName() const;
+
+ void setDescription(const QString &description);
+ QString description() const;
+
+ void setDefaultValue(const QString &defaultValue);
+ void setDefaultValues(const QStringList &defaultValues);
+ QStringList defaultValues() const;
+
+private:
+ QSharedDataPointer<QCommandLineOptionPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOMMANDLINEOPTION_H
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
new file mode 100644
index 0000000000..ae6079ab0b
--- /dev/null
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -0,0 +1,896 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
+** Copyright (C) 2013 David Faure <faure@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommandlineparser.h"
+
+#include <qcoreapplication.h>
+#include <qhash.h>
+#include <qvector.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef QHash<QString, int> NameHash_t;
+
+// Special value for "not found" when doing hash lookups.
+static const NameHash_t::mapped_type optionNotFound = ~0;
+
+class QCommandLineParserPrivate
+{
+public:
+ inline QCommandLineParserPrivate()
+ : singleDashWordOptionMode(QCommandLineParser::ParseAsCompactedShortOptions),
+ builtinVersionOption(false),
+ builtinHelpOption(false),
+ needsParsing(true)
+ { }
+
+ bool parse(const QStringList &args);
+ void checkParsed(const char *method);
+ QStringList aliases(const QString &name) const;
+ QString helpText() const;
+ bool registerFoundOption(const QString &optionName);
+ bool parseOptionValue(const QString &optionName, const QString &argument,
+ QStringList::const_iterator *argumentIterator,
+ QStringList::const_iterator argsEnd);
+
+ //! Error text set when parse() returns false
+ QString errorText;
+
+ //! The command line options used for parsing
+ QList<QCommandLineOption> commandLineOptionList;
+
+ //! Hash mapping option names to their offsets in commandLineOptionList and optionArgumentList.
+ NameHash_t nameHash;
+
+ //! Option values found (only for options with a value)
+ QHash<int, QStringList> optionValuesHash;
+
+ //! Names of options found on the command line.
+ QStringList optionNames;
+
+ //! Arguments which did not belong to any option.
+ QStringList positionalArgumentList;
+
+ //! Names of options which were unknown.
+ QStringList unknownOptionNames;
+
+ //! Application description
+ QString description;
+
+ //! Documentation for positional arguments
+ struct PositionalArgumentDefinition
+ {
+ QString name;
+ QString description;
+ QString syntax;
+ };
+ QVector<PositionalArgumentDefinition> positionalArgumentDefinitions;
+
+ //! The parsing mode for "-abc"
+ QCommandLineParser::SingleDashWordOptionMode singleDashWordOptionMode;
+
+ //! Whether addVersionOption was called
+ bool builtinVersionOption;
+
+ //! Whether addHelpOption was called
+ bool builtinHelpOption;
+
+ //! True if parse() needs to be called
+ bool needsParsing;
+};
+
+QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const
+{
+ const NameHash_t::mapped_type optionOffset = nameHash.value(optionName, optionNotFound);
+ if (optionOffset == optionNotFound) {
+ qWarning("QCommandLineParser: option not defined: \"%s\"", qPrintable(optionName));
+ return QStringList();
+ }
+ return commandLineOptionList.at(optionOffset).names();
+}
+
+/*!
+ \since 5.2
+ \class QCommandLineParser
+ \inmodule QtCore
+ \ingroup tools
+
+ \brief The QCommandLineParser class provides a means for handling the
+ command line options.
+
+ QCoreApplication provides the command-line arguments as a simple list of strings.
+ QCommandLineParser provides the ability to define a set of options, parse the
+ command-line arguments, and store which options have actually been used, as
+ well as option values.
+
+ Any argument that isn't an option (i.e. doesn't start with a \c{-}) is stored
+ as a "positional argument".
+
+ The parser handles short names, long names, more than one name for the same
+ option, and option values.
+
+ Options on the command line are recognized as starting with a single or
+ double \c{-} character(s).
+ The option \c{-} (single dash alone) is a special case, often meaning standard
+ input, and not treated as an option. The parser will treat everything after the
+ option \c{--} (double dash) as positional arguments.
+
+ Short options are single letters. The option \c{v} would be specified by
+ passing \c{-v} on the command line. In the default parsing mode, short options
+ can be written in a compact form, for instance \c{-abc} is equivalent to \c{-a -b -c}.
+ The parsing mode for can be set to ParseAsLongOptions, in which case \c{-abc}
+ will be parsed as the long option \a{abc}.
+
+ Long options are more than one letter long and cannot be compacted together.
+ The long option \c{verbose} would be passed as \c{--verbose} or \c{-verbose}.
+
+ Passing values to options can be done using the assignment operator: \c{-v=value}
+ \c{--verbose=value}, or a space: \c{-v value} \c{--verbose value}, i.e. the next
+ argument is used as value (even if it starts with a \c{-}).
+
+ The parser does not support optional values - if an option is set to
+ require a value, one must be present. If such an option is placed last
+ and has no value, the option will be treated as if it had not been
+ specified.
+
+ The parser does not automatically support negating or disabling long options
+ by using the format \c{--disable-option} or \c{--no-option}. However, it is
+ possible to handle this case explicitly by making an option with \c{no-option}
+ as one of its names, and handling the option explicitly.
+
+ Example:
+ \snippet code/src_corelib_tools_qcommandlineparser.cpp 3
+
+ Known limitation: the parsing of Qt options inside QCoreApplication and subclasses
+ happens before QCommandLineParser exists, so it can't take it into account. This
+ means any option value that looks like a builtin Qt option, will be treated by
+ QCoreApplication as a builtin Qt option. Example: \c{--profile -reverse} will
+ lead to QGuiApplication seeing the -reverse option set, and removing it from
+ QCoreApplication::arguments() before QCommandLineParser defines the \c{profile}
+ option and parses the command line.
+
+ \sa QCommandLineOption, QCoreApplication
+*/
+
+/*!
+ Constructs a command line parser object.
+*/
+QCommandLineParser::QCommandLineParser()
+ : d(new QCommandLineParserPrivate)
+{
+}
+
+/*!
+ Destroys the command line parser object.
+*/
+QCommandLineParser::~QCommandLineParser()
+{
+ delete d;
+}
+
+/*!
+ \enum QCommandLineParser::SingleDashWordOptionMode
+
+ This enum describes the way the parser interprets command-line
+ options that use a single dash followed by multiple letters, as as \c{-abc}.
+
+ \value ParseAsCompactedShortOptions \c{-abc} is interpreted as \c{-a -b -c},
+ i.e. as three short options that have been compacted on the command-line,
+ if none of the options take a value. If \c{a} takes a value, then it
+ is interpreted as \c{-a bc}, i.e. the short option \c{a} followed by the value \c{bc}.
+ This is typically used in tools that behave like compilers, in order
+ to handle options such as \c{-DDEFINE=VALUE} or \c{-I/include/path}.
+ This is the default parsing mode. New applications are recommended to
+ use this mode.
+
+ \value ParseAsLongOptions \c{-abc} is interpreted as \c{--abc},
+ i.e. as the long option named \c{abc}. This is how Qt's own tools
+ (uic, rcc...) have always been parsing arguments. This mode should be
+ used for preserving compatibility in applications that were parsing
+ arguments in such a way.
+
+ \sa setSingleDashWordOptionMode()
+*/
+
+/*!
+ Sets the parsing mode to \a singleDashWordOptionMode.
+ This must be called before process() or parse().
+*/
+void QCommandLineParser::setSingleDashWordOptionMode(QCommandLineParser::SingleDashWordOptionMode singleDashWordOptionMode)
+{
+ d->singleDashWordOptionMode = singleDashWordOptionMode;
+}
+
+/*!
+ Adds the option \a option to look for while parsing.
+
+ Returns true if adding the option was successful; otherwise returns false.
+
+ Adding the option fails if there is no name attached to the option, or
+ the option has a name that clashes with an option name added before.
+ */
+bool QCommandLineParser::addOption(const QCommandLineOption &option)
+{
+ QStringList optionNames = option.names();
+
+ if (!optionNames.isEmpty()) {
+ foreach (const QString &name, optionNames) {
+ if (d->nameHash.contains(name))
+ return false;
+ }
+
+ d->commandLineOptionList.append(option);
+
+ const int offset = d->commandLineOptionList.size() - 1;
+ foreach (const QString &name, optionNames)
+ d->nameHash.insert(name, offset);
+
+ return true;
+ }
+
+ return false;
+}
+
+/*!
+ Adds the \c{-v} / \c{--version} option, which displays the version string of the application.
+
+ This option is handled automatically by QCommandLineParser.
+
+ You can set the actual version string by using QCoreApplication::setApplicationVersion().
+
+ Returns the option instance, which can be used to call isSet().
+*/
+QCommandLineOption QCommandLineParser::addVersionOption()
+{
+ d->builtinVersionOption = true;
+ QCommandLineOption opt(QStringList() << QStringLiteral("v") << QStringLiteral("version"), tr("Displays version information."));
+ addOption(opt);
+ return opt;
+}
+
+/*!
+ Adds the help option (\c{-h}, \c{--help} and \c{-?} on Windows)
+ This option is handled automatically by QCommandLineParser.
+
+ Remember to use setApplicationDescription to set the application description,
+ which will be displayed when this option is used.
+
+ Example:
+ \code
+ setApplicationDescription(QCoreApplication::translate("main", "The best application in the world"));
+ addHelpOption();
+ \endcode
+
+ Returns the option instance, which can be used to call isSet().
+*/
+QCommandLineOption QCommandLineParser::addHelpOption()
+{
+ d->builtinHelpOption = true;
+ QCommandLineOption opt(QStringList()
+#ifdef Q_OS_WIN
+ << QStringLiteral("?")
+#endif
+ << QStringLiteral("h")
+ << QStringLiteral("help"), tr("Displays this help."));
+ addOption(opt);
+ return opt;
+}
+
+/*!
+ Sets the application \a description shown by helpText().
+ Most applications don't need to call this directly, addHelpOption()
+ also sets the application description.
+*/
+void QCommandLineParser::setApplicationDescription(const QString &description)
+{
+ d->description = description;
+}
+
+/*!
+ Returns the application description set in setApplicationDescription()
+ or addHelpOption().
+*/
+QString QCommandLineParser::applicationDescription() const
+{
+ return d->description;
+}
+
+/*!
+ Defines an additional argument to the application, for the benefit of the help text.
+
+ The argument \a name and \a description will appear under the \c{Arguments:} section
+ of the help. If \a syntax is specified, it will be appended to the Usage line, otherwise
+ the \a name will be appended.
+
+ Example:
+ \snippet code/src_corelib_tools_qcommandlineparser.cpp 1
+
+ \sa addHelpOption(), helpText()
+*/
+void QCommandLineParser::addPositionalArgument(const QString &name, const QString &description, const QString &syntax)
+{
+ QCommandLineParserPrivate::PositionalArgumentDefinition arg;
+ arg.name = name;
+ arg.description = description;
+ arg.syntax = syntax.isEmpty() ? name : syntax;
+ d->positionalArgumentDefinitions.append(arg);
+}
+
+/*!
+ Clears the definitions of additional arguments from the help text.
+
+ This is only needed for the special case of tools which support multiple commands
+ with different options. Once the actual command has been identified, the options
+ for this command can be defined, and the help text for the command can be adjusted
+ accordingly.
+
+ Example:
+ \snippet code/src_corelib_tools_qcommandlineparser.cpp 2
+*/
+void QCommandLineParser::clearPositionalArguments()
+{
+ d->positionalArgumentDefinitions.clear();
+}
+
+/*!
+ Parses the command line \a arguments.
+
+ Most programs don't need to call this, a simple call to process(app) is enough.
+
+ parse() is more low-level, and only does the parsing. The application will have to
+ take care of the error handling, using errorText() if parse() returns false.
+ This can be useful for instance to show a graphical error message in graphical programs.
+
+ Calling parse() instead of process() can also be useful in order to ignore unknown
+ options temporarily, because more option definitions will be provided later on
+ (depending on one of the arguments), before calling process().
+
+ Don't forget that \a arguments must start with the name of the executable (ignored, though).
+
+ Return false in case of a parse error (unknown option or missing value); returns true otherwise.
+
+ \sa process()
+*/
+bool QCommandLineParser::parse(const QStringList &arguments)
+{
+ return d->parse(arguments);
+}
+
+/*!
+ Returns a translated error text for the user.
+ This should only be called when parse() returns false.
+*/
+QString QCommandLineParser::errorText() const
+{
+ if (!d->errorText.isEmpty())
+ return d->errorText;
+ if (d->unknownOptionNames.count() == 1)
+ return tr("Unknown option '%1'.").arg(d->unknownOptionNames.first());
+ if (d->unknownOptionNames.count() > 1)
+ return tr("Unknown options: %1.").arg(d->unknownOptionNames.join(QStringLiteral(", ")));
+ return QString();
+}
+
+/*!
+ Processes the command line \a arguments.
+
+ This means both parsing them, and handling the builtin options,
+ \c{--version} if addVersionOption was called, \c{--help} if addHelpOption was called,
+ as well as giving an error on unknown option names.
+ In each of these three cases, the current process will then stop, using the exit() function.
+
+ \sa QCoreApplication::arguments(), parse()
+ */
+void QCommandLineParser::process(const QStringList &arguments)
+{
+ if (!d->parse(arguments)) {
+ fprintf(stderr, "%s\n", qPrintable(errorText()));
+ ::exit(1);
+ }
+
+ if (d->builtinVersionOption && isSet(QStringLiteral("version"))) {
+ printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion()));
+ ::exit(0);
+ }
+
+ if (d->builtinHelpOption && isSet(QStringLiteral("help")))
+ showHelp(0);
+}
+
+/*!
+ \overload
+
+ The command line is obtained from the QCoreApplication instance \a app.
+ */
+void QCommandLineParser::process(const QCoreApplication &app)
+{
+ // QCoreApplication::arguments() is static, but the app instance must exist so we require it as parameter
+ Q_UNUSED(app);
+ process(QCoreApplication::arguments());
+}
+
+void QCommandLineParserPrivate::checkParsed(const char *method)
+{
+ if (needsParsing)
+ qWarning("QCommandLineParser: call process() or parse() before %s", method);
+}
+
+/*!
+ \internal
+ Looks up the option \a optionName (found on the command line) and register it as found.
+ Returns true on success.
+ */
+bool QCommandLineParserPrivate::registerFoundOption(const QString &optionName)
+{
+ if (nameHash.contains(optionName)) {
+ optionNames.append(optionName);
+ return true;
+ } else {
+ unknownOptionNames.append(optionName);
+ return false;
+ }
+}
+
+/*!
+ \internal
+ \brief Parse the value for a given option, if it was defined to expect one.
+
+ The value is taken from the next argument, or after the equal sign in \a argument.
+
+ \param optionName the short option name
+ \param argument the argument from the command line currently parsed. Only used for -k=value parsing.
+ \param argumentIterator iterator to the currently parsed argument. Incremented if the next argument contains the value.
+ \param argsEnd args.end(), to check if ++argumentIterator goes out of bounds
+ Returns true on success.
+ */
+bool QCommandLineParserPrivate::parseOptionValue(const QString &optionName, const QString &argument,
+ QStringList::const_iterator *argumentIterator, QStringList::const_iterator argsEnd)
+{
+ const QLatin1Char assignChar('=');
+ const NameHash_t::const_iterator nameHashIt = nameHash.constFind(optionName);
+ if (nameHashIt != nameHash.constEnd()) {
+ const int assignPos = argument.indexOf(assignChar);
+ const NameHash_t::mapped_type optionOffset = *nameHashIt;
+ const bool withValue = !commandLineOptionList.at(optionOffset).valueName().isEmpty();
+ if (withValue) {
+ if (assignPos == -1) {
+ ++(*argumentIterator);
+ if (*argumentIterator == argsEnd) {
+ errorText = QCommandLineParser::tr("Missing value after '%1'.").arg(argument);
+ return false;
+ }
+ optionValuesHash[optionOffset].append(*(*argumentIterator));
+ } else {
+ optionValuesHash[optionOffset].append(argument.mid(assignPos + 1));
+ }
+ } else {
+ if (assignPos != -1) {
+ errorText = QCommandLineParser::tr("Unexpected value after '%1'.").arg(argument.left(assignPos));
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Parse the list of arguments \a arguments.
+
+ Any results from a previous parse operation are removed.
+ The parser will not look for further options once it encounters the option
+ \c{--}; this does not include when \c{--} follows an option that requires a value.
+
+ Options that were successfully recognized, and their values, are
+ removed from the input list. If \c m_bRemoveUnknownLongNames is
+ \c true, unrecognized options are removed and placed into a list of
+ unknown option names. Anything left over is placed into a list of
+ leftover arguments.
+ */
+bool QCommandLineParserPrivate::parse(const QStringList &args)
+{
+ needsParsing = false;
+ bool error = false;
+
+ const QString doubleDashString(QStringLiteral("--"));
+ const QLatin1Char dashChar('-');
+ const QLatin1Char assignChar('=');
+
+ bool doubleDashFound = false;
+ errorText.clear();
+ positionalArgumentList.clear();
+ optionNames.clear();
+ unknownOptionNames.clear();
+ optionValuesHash.clear();
+
+ if (args.isEmpty()) {
+ qWarning("QCommandLineParser: argument list cannot be empty, it should contain at least the executable name");
+ return false;
+ }
+
+ QStringList::const_iterator argumentIterator = args.begin();
+ ++argumentIterator; // skip executable name
+
+ for (; argumentIterator != args.end() ; ++argumentIterator) {
+ QString argument = *argumentIterator;
+
+ if (doubleDashFound) {
+ positionalArgumentList.append(argument);
+ } else if (argument.startsWith(doubleDashString)) {
+ if (argument.length() > 2) {
+ QString optionName = argument.mid(2).section(assignChar, 0, 0);
+ if (registerFoundOption(optionName)) {
+ if (!parseOptionValue(optionName, argument, &argumentIterator, args.end()))
+ error = true;
+ } else {
+ error = true;
+ }
+ } else {
+ doubleDashFound = true;
+ }
+ } else if (argument.startsWith(dashChar)) {
+ if (argument.size() == 1) { // single dash ("stdin")
+ positionalArgumentList.append(argument);
+ continue;
+ }
+ switch (singleDashWordOptionMode) {
+ case QCommandLineParser::ParseAsCompactedShortOptions:
+ {
+ QString optionName;
+ bool valueFound = false;
+ for (int pos = 1 ; pos < argument.size(); ++pos) {
+ optionName = argument.mid(pos, 1);
+ if (!registerFoundOption(optionName)) {
+ error = true;
+ } else {
+ const NameHash_t::const_iterator nameHashIt = nameHash.constFind(optionName);
+ Q_ASSERT(nameHashIt != nameHash.constEnd()); // checked by registerFoundOption
+ const NameHash_t::mapped_type optionOffset = *nameHashIt;
+ const bool withValue = !commandLineOptionList.at(optionOffset).valueName().isEmpty();
+ if (withValue) {
+ if (pos + 1 < argument.size()) {
+ if (argument.at(pos + 1) == assignChar)
+ ++pos;
+ optionValuesHash[optionOffset].append(argument.mid(pos + 1));
+ valueFound = true;
+ }
+ break;
+ }
+ if (pos + 1 < argument.size() && argument.at(pos + 1) == assignChar)
+ break;
+ }
+ }
+ if (!valueFound && !parseOptionValue(optionName, argument, &argumentIterator, args.end()))
+ error = true;
+ break;
+ }
+ case QCommandLineParser::ParseAsLongOptions:
+ {
+ const QString optionName = argument.mid(1).section(assignChar, 0, 0);
+ if (registerFoundOption(optionName)) {
+ if (!parseOptionValue(optionName, argument, &argumentIterator, args.end()))
+ error = true;
+ } else {
+ error = true;
+ }
+ break;
+ }
+ }
+ } else {
+ positionalArgumentList.append(argument);
+ }
+ if (argumentIterator == args.end())
+ break;
+ }
+ return !error;
+}
+
+/*!
+ Checks whether the option \a name was passed to the application.
+
+ Returns true if the option \a name was set, false otherwise.
+
+ This is the recommended way to check for options with no values.
+
+ The name provided can be any long or short name of any option that was
+ added with \c addOption(). All the options names are treated as being
+ equivalent. If the name is not recognized or that option was not present,
+ false is returned.
+
+ Example:
+ \snippet code/src_corelib_tools_qcommandlineparser.cpp 0
+ */
+
+bool QCommandLineParser::isSet(const QString &name) const
+{
+ d->checkParsed("isSet");
+ if (d->optionNames.contains(name))
+ return true;
+ const QStringList aliases = d->aliases(name);
+ foreach (const QString &optionName, d->optionNames) {
+ if (aliases.contains(optionName))
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns the option value found for the given option name \a optionName, or
+ an empty string if not found.
+
+ The name provided can be any long or short name of any option that was
+ added with \c addOption(). All the option names are treated as being
+ equivalent. If the name is not recognized or that option was not present, an
+ empty string is returned.
+
+ For options found by the parser, the last value found for
+ that option is returned. If the option wasn't specified on the command line,
+ the default value is returned.
+
+ An empty string is returned if the option does not take a value.
+
+ \sa values()
+ */
+
+QString QCommandLineParser::value(const QString &optionName) const
+{
+ d->checkParsed("value");
+ const QStringList valueList = values(optionName);
+
+ if (!valueList.isEmpty())
+ return valueList.last();
+
+ return QString();
+}
+
+/*!
+ Returns a list of option values found for the given option name \a
+ optionName, or an empty list if not found.
+
+ The name provided can be any long or short name of any option that was
+ added with \c addOption(). All the options names are treated as being
+ equivalent. If the name is not recognized or that option was not present, an
+ empty list is returned.
+
+ For options found by the parser, the list will contain an entry for
+ each time the option was encountered by the parser. If the option wasn't
+ specified on the command line, the default values are returned.
+
+ An empty list is returned if the option does not take a value.
+
+ \sa value()
+ */
+
+QStringList QCommandLineParser::values(const QString &optionName) const
+{
+ d->checkParsed("values");
+ const NameHash_t::mapped_type optionOffset = d->nameHash.value(optionName, optionNotFound);
+ if (optionOffset != optionNotFound) {
+ QStringList values = d->optionValuesHash.value(optionOffset);
+ if (values.isEmpty())
+ values = d->commandLineOptionList.at(optionOffset).defaultValues();
+ return values;
+ }
+
+ qWarning("QCommandLineParser: option not defined: \"%s\"", qPrintable(optionName));
+ return QStringList();
+}
+
+/*!
+ \overload
+ Returns true if the \a option was set, false otherwise.
+*/
+bool QCommandLineParser::isSet(const QCommandLineOption &option) const
+{
+ return isSet(option.names().first());
+}
+
+/*!
+ \overload
+ Returns the option value found for the given \a option, or
+ an empty string if not found.
+*/
+QString QCommandLineParser::value(const QCommandLineOption &option) const
+{
+ return value(option.names().first());
+}
+
+/*!
+ \overload
+ Returns a list of option values found for the given \a option,
+ or an empty list if not found.
+*/
+QStringList QCommandLineParser::values(const QCommandLineOption &option) const
+{
+ return values(option.names().first());
+}
+
+/*!
+ Returns a list of positional arguments.
+
+ These are all of the arguments that were not recognized as part of an
+ option.
+ */
+
+QStringList QCommandLineParser::positionalArguments() const
+{
+ d->checkParsed("positionalArguments");
+ return d->positionalArgumentList;
+}
+
+/*!
+ Returns a list of option names that were found.
+
+ This returns a list of all the recognized option names found by the
+ parser, in the order in which they were found. For any long options
+ that were in the form {--option=value}, the value part will have been
+ dropped.
+
+ The names in this list do not include the preceding dash characters.
+ Names may appear more than once in this list if they were encountered
+ more than once by the parser.
+
+ Any entry in the list can be used with \c value() or with
+ \c values() to get any relevant option values.
+ */
+
+QStringList QCommandLineParser::optionNames() const
+{
+ d->checkParsed("optionNames");
+ return d->optionNames;
+}
+
+/*!
+ Returns a list of unknown option names.
+
+ This list will include both long an short name options that were not
+ recognized. For any long options that were in the form {--option=value},
+ the value part will have been dropped and only the long name is added.
+
+ The names in this list do not include the preceding dash characters.
+ Names may appear more than once in this list if they were encountered
+ more than once by the parser.
+
+ \sa optionNames()
+ */
+
+QStringList QCommandLineParser::unknownOptionNames() const
+{
+ d->checkParsed("unknownOptionNames");
+ return d->unknownOptionNames;
+}
+
+/*!
+ Displays the help information, and exits the application.
+ This is automatically triggered by the --help option, but can also
+ be used to display the help when the user is not invoking the
+ application correctly.
+ The exit code is set to \a exitCode. It should be set to 0 if the
+ user requested to see the help, and to any other value in case of
+ an error.
+
+ \sa helpText()
+*/
+Q_NORETURN void QCommandLineParser::showHelp(int exitCode)
+{
+ fprintf(stdout, "%s", qPrintable(d->helpText()));
+ ::exit(exitCode);
+}
+
+/*!
+ Returns a string containing the complete help information.
+
+ \sa showHelp()
+*/
+QString QCommandLineParser::helpText() const
+{
+ return d->helpText();
+}
+
+static QString wrapText(const QString &names, int longestOptionNameString, const QString &description)
+{
+ const QLatin1Char nl('\n');
+ QString text = QStringLiteral(" ") + names.leftJustified(longestOptionNameString) + QLatin1Char(' ');
+ const int leftColumnWidth = text.length();
+ const int rightColumnWidth = 79 - leftColumnWidth;
+ text += description.left(rightColumnWidth) + nl;
+ for (int n = rightColumnWidth; n < description.length(); n += rightColumnWidth)
+ text += QStringLiteral(" ").repeated(leftColumnWidth) + description.mid(n, rightColumnWidth) + nl;
+ return text;
+}
+
+QString QCommandLineParserPrivate::helpText() const
+{
+ const QLatin1Char nl('\n');
+ QString text;
+ const QString exeName = QCoreApplication::instance()->arguments().first();
+ QString usage = exeName;
+ if (!commandLineOptionList.isEmpty()) {
+ usage += QLatin1Char(' ');
+ usage += QCommandLineParser::tr("[options]");
+ }
+ foreach (const PositionalArgumentDefinition &arg, positionalArgumentDefinitions) {
+ usage += QLatin1Char(' ');
+ usage += arg.syntax;
+ }
+ text += QCommandLineParser::tr("Usage: %1").arg(usage) + nl;
+ if (!description.isEmpty())
+ text += description + nl;
+ text += nl;
+ if (!commandLineOptionList.isEmpty())
+ text += QCommandLineParser::tr("Options:") + nl;
+ QStringList optionNameList;
+ int longestOptionNameString = 0;
+ foreach (const QCommandLineOption &option, commandLineOptionList) {
+ QStringList optionNames;
+ foreach (const QString &optionName, option.names()) {
+ if (optionName.length() == 1)
+ optionNames.append(QLatin1Char('-') + optionName);
+ else
+ optionNames.append(QStringLiteral("--") + optionName);
+ }
+ QString optionNamesString = optionNames.join(QStringLiteral(", "));
+ if (!option.valueName().isEmpty())
+ optionNamesString += QStringLiteral(" <") + option.valueName() + QLatin1Char('>');
+ optionNameList.append(optionNamesString);
+ longestOptionNameString = qMax(longestOptionNameString, optionNamesString.length());
+ }
+ ++longestOptionNameString;
+ for (int i = 0; i < commandLineOptionList.count(); ++i) {
+ const QCommandLineOption &option = commandLineOptionList.at(i);
+ text += wrapText(optionNameList.at(i), longestOptionNameString, option.description());
+ }
+ if (!positionalArgumentDefinitions.isEmpty()) {
+ if (!commandLineOptionList.isEmpty())
+ text += nl;
+ text += QCommandLineParser::tr("Arguments:") + nl;
+ foreach (const PositionalArgumentDefinition &arg, positionalArgumentDefinitions) {
+ text += wrapText(arg.name, longestOptionNameString, arg.description);
+ }
+ }
+ return text;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qcommandlineparser.h b/src/corelib/tools/qcommandlineparser.h
new file mode 100644
index 0000000000..5a7061f031
--- /dev/null
+++ b/src/corelib/tools/qcommandlineparser.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMMANDLINEPARSER_H
+#define QCOMMANDLINEPARSER_H
+
+#include <QtCore/qstringlist.h>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qcommandlineoption.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCommandLineParserPrivate;
+class QCoreApplication;
+
+class Q_CORE_EXPORT QCommandLineParser
+{
+ Q_DECLARE_TR_FUNCTIONS(QCommandLineParser)
+public:
+ QCommandLineParser();
+ ~QCommandLineParser();
+
+ enum SingleDashWordOptionMode {
+ ParseAsCompactedShortOptions,
+ ParseAsLongOptions
+ };
+ void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode);
+
+ bool addOption(const QCommandLineOption &commandLineOption);
+
+ QCommandLineOption addVersionOption();
+ QCommandLineOption addHelpOption();
+ void setApplicationDescription(const QString &description);
+ QString applicationDescription() const;
+ void addPositionalArgument(const QString &name, const QString &description, const QString &syntax = QString());
+ void clearPositionalArguments();
+
+ void process(const QStringList &arguments);
+ void process(const QCoreApplication &app);
+
+ bool parse(const QStringList &arguments);
+ QString errorText() const;
+
+ bool isSet(const QString &name) const;
+ QString value(const QString &name) const;
+ QStringList values(const QString &name) const;
+
+ bool isSet(const QCommandLineOption &option) const;
+ QString value(const QCommandLineOption &option) const;
+ QStringList values(const QCommandLineOption &option) const;
+
+ QStringList positionalArguments() const;
+ QStringList optionNames() const;
+ QStringList unknownOptionNames() const;
+
+ Q_NORETURN void showHelp(int exitCode = 0);
+ QString helpText() const;
+
+private:
+ Q_DISABLE_COPY(QCommandLineParser)
+
+ QCommandLineParserPrivate * const d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOMMANDLINEPARSER_H
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index d8e3a78cdf..ab5a516e8a 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -158,10 +158,135 @@ static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
static const char * const qt_shortMonthNames[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+int qt_monthNumberFromShortName(const QString &shortName)
+{
+ for (unsigned int i = 0; i < sizeof(qt_shortMonthNames) / sizeof(qt_shortMonthNames[0]); ++i) {
+ if (shortName == QLatin1String(qt_shortMonthNames[i]))
+ return i + 1;
+ }
+ return -1;
+}
#endif
+
#ifndef QT_NO_DATESTRING
-static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);
+static void rfcDateImpl(const QString &s, QDate *dd = 0, QTime *dt = 0, int *utfcOffset = 0);
#endif
+static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time);
+static void utcToOffset(QDate *date, QTime *time, qint32 offset);
+static QDate adjustDate(QDate date);
+
+// Return offset in [+-]HH:MM format
+// Qt::ISODate puts : between the hours and minutes, but Qt:TextDate does not
+static QString toOffsetString(Qt::DateFormat format, int offset)
+{
+ QString result;
+ if (format == Qt::TextDate)
+ result = QStringLiteral("%1%2%3");
+ else // Qt::ISODate
+ result = QStringLiteral("%1%2:%3");
+
+ return result.arg(offset >= 0 ? QLatin1Char('+') : QLatin1Char('-'))
+ .arg(qAbs(offset) / SECS_PER_HOUR, 2, 10, QLatin1Char('0'))
+ .arg((offset / 60) % 60, 2, 10, QLatin1Char('0'));
+}
+
+// Parse offset in [+-]HH[:]MM format
+static int fromOffsetString(const QString &offsetString, bool *valid)
+{
+ *valid = false;
+
+ const int size = offsetString.size();
+ if (size < 2 || size > 6)
+ return 0;
+
+ // First char must be + or -
+ const QChar sign = offsetString.at(0);
+ if (sign != QLatin1Char('+') && sign != QLatin1Char('-'))
+ return 0;
+
+ // Split the hour and minute parts
+ QStringList parts = offsetString.split(QLatin1Char(':'));
+ if (parts.count() == 1) {
+ // [+-]HHMM format
+ parts.append(parts.at(0).mid(3));
+ parts[0] = parts.at(0).left(3);
+ }
+
+ bool ok = false;
+ const int hour = parts.at(0).toInt(&ok);
+ if (!ok)
+ return 0;
+
+ const int minute = parts.at(1).toInt(&ok);
+ if (!ok || minute < 0 || minute > 59)
+ return 0;
+
+ *valid = true;
+ return ((hour * 60) + minute) * 60;
+}
+
+#if !defined(Q_OS_WINCE)
+// Calls the platform variant of mktime for the given date and time,
+// and updates the date, time, spec and abbreviation with the returned values
+// If the date falls outside the 1970 to 2037 range supported by mktime / time_t
+// then null date/time will be returned, you should call adjustDate() first if
+// you need a guaranteed result.
+static time_t qt_mktime(QDate *date, QTime *time, QDateTimePrivate::Spec *spec,
+ QString *abbreviation, bool *ok)
+{
+ if (ok)
+ *ok = false;
+ int yy, mm, dd;
+ date->getDate(&yy, &mm, &dd);
+ tm local;
+ local.tm_sec = time->second();
+ local.tm_min = time->minute();
+ local.tm_hour = time->hour();
+ local.tm_mday = dd;
+ local.tm_mon = mm - 1;
+ local.tm_year = yy - 1900;
+ local.tm_wday = 0;
+ local.tm_yday = 0;
+ local.tm_isdst = -1;
+#if defined(Q_OS_WIN)
+ _tzset();
+#else
+ tzset();
+#endif // Q_OS_WIN
+ const time_t secsSinceEpoch = mktime(&local);
+ if (secsSinceEpoch != time_t(-1)) {
+ *date = QDate(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday);
+ *time = QTime(local.tm_hour, local.tm_min, local.tm_sec, time->msec());
+ if (local.tm_isdst == 1) {
+ if (spec)
+ *spec = QDateTimePrivate::LocalDST;
+ if (abbreviation)
+ *abbreviation = QString::fromLocal8Bit(tzname[1]);
+ } else if (local.tm_isdst == 0) {
+ if (spec)
+ *spec = QDateTimePrivate::LocalStandard;
+ if (abbreviation)
+ *abbreviation = QString::fromLocal8Bit(tzname[0]);
+ } else {
+ if (spec)
+ *spec = QDateTimePrivate::LocalUnknown;
+ if (abbreviation)
+ *abbreviation = QString::fromLocal8Bit(tzname[0]);
+ }
+ if (ok)
+ *ok = true;
+ } else {
+ *date = QDate();
+ *time = QTime();
+ if (spec)
+ *spec = QDateTimePrivate::LocalUnknown;
+ if (abbreviation)
+ *abbreviation = QString();
+ }
+ return secsSinceEpoch;
+}
+#endif // !Q_OS_WINCE
/*****************************************************************************
QDate member functions
@@ -543,8 +668,8 @@ int QDate::weekNumber(int *yearNumber) const
\li 12 = "Dec"
\endlist
- The month names will be localized according to the system's default
- locale settings.
+ The month names will be localized according to the system's
+ locale settings, i.e. using QLocale::system().
Returns an empty string if the date is invalid.
@@ -590,8 +715,8 @@ QString QDate::shortMonthName(int month, QDate::MonthNameType type)
\li 12 = "December"
\endlist
- The month names will be localized according to the system's default
- locale settings.
+ The month names will be localized according to the system's
+ locale settings, i.e. using QLocale::system().
Returns an empty string if the date is invalid.
@@ -632,8 +757,8 @@ QString QDate::longMonthName(int month, MonthNameType type)
\li 7 = "Sun"
\endlist
- The day names will be localized according to the system's default
- locale settings.
+ The day names will be localized according to the system's
+ locale settings, i.e. using QLocale::system().
Returns an empty string if the date is invalid.
@@ -674,8 +799,8 @@ QString QDate::shortDayName(int weekday, MonthNameType type)
\li 7 = "Sunday"
\endlist
- The day names will be localized according to the system's default
- locale settings.
+ The day names will be localized according to the system's
+ locale settings, i.e. using QLocale::system().
Returns an empty string if the date is invalid.
@@ -712,7 +837,7 @@ QString QDate::longDayName(int weekday, MonthNameType type)
If the \a format is Qt::TextDate, the string is formatted in
the default way. QDate::shortDayName() and QDate::shortMonthName()
are used to generate the string, so the day and month names will
- be localized names using the default locale from the system. An
+ be localized names using the system locale, i.e. QLocale::system(). An
example of this formatting is "Sat May 20 1995".
If the \a format is Qt::ISODate, the string format corresponds
@@ -735,6 +860,10 @@ QString QDate::longDayName(int weekday, MonthNameType type)
QLocale::ShortFormat) or QLocale().toString(date,
QLocale::LongFormat).
+ If the \a format is Qt::RFC2822Date, the string is formatted in
+ an \l{RFC 2822} compatible way. An example of this formatting is
+ "20 May 1995".
+
If the date is invalid, an empty string will be returned.
\warning The Qt::ISODate format is only valid for years in the
@@ -743,43 +872,42 @@ QString QDate::longDayName(int weekday, MonthNameType type)
\sa shortDayName(), shortMonthName()
*/
-QString QDate::toString(Qt::DateFormat f) const
+QString QDate::toString(Qt::DateFormat format) const
{
if (!isValid())
return QString();
+
int y, m, d;
- getDateFromJulianDay(jd, &y, &m, &d);
- switch (f) {
+
+ switch (format) {
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
+ return QLocale::system().toString(*this, QLocale::ShortFormat);
case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat);
+ return QLocale::system().toString(*this, QLocale::LongFormat);
case Qt::LocaleDate:
case Qt::DefaultLocaleShortDate:
+ return QLocale().toString(*this, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat);
+ return QLocale().toString(*this, QLocale::LongFormat);
+ case Qt::RFC2822Date:
+ return toString(QStringLiteral("dd MMM yyyy"));
default:
#ifndef QT_NO_TEXTDATE
case Qt::TextDate:
- {
- return QString::fromLatin1("%0 %1 %2 %3")
- .arg(shortDayName(dayOfWeek()))
- .arg(shortMonthName(m))
- .arg(d)
- .arg(y);
- }
+ getDateFromJulianDay(jd, &y, &m, &d);
+ return QString::fromUtf8("%1 %2 %3 %4").arg(shortDayName(dayOfWeek()))
+ .arg(shortMonthName(m))
+ .arg(d)
+ .arg(y);
#endif
case Qt::ISODate:
- {
- if (year() < 0 || year() > 9999)
- return QString();
- QString year(QString::number(y).rightJustified(4, QLatin1Char('0')));
- QString month(QString::number(m).rightJustified(2, QLatin1Char('0')));
- QString day(QString::number(d).rightJustified(2, QLatin1Char('0')));
- return year + QLatin1Char('-') + month + QLatin1Char('-') + day;
- }
+ getDateFromJulianDay(jd, &y, &m, &d);
+ if (y < 0 || y > 9999)
+ return QString();
+ return QString::fromUtf8("%1-%2-%3").arg(y, 4, 10, QLatin1Char('0'))
+ .arg(m, 2, 10, QLatin1Char('0'))
+ .arg(d, 2, 10, QLatin1Char('0'));
}
}
@@ -795,18 +923,18 @@ QString QDate::toString(Qt::DateFormat f) const
\row \li dd \li the day as number with a leading zero (01 to 31)
\row \li ddd
\li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
- Uses QDate::shortDayName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li dddd
\li the long localized day name (e.g. 'Monday' to 'Sunday').
- Uses QDate::longDayName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li M \li the month as number without a leading zero (1 to 12)
\row \li MM \li the month as number with a leading zero (01 to 12)
\row \li MMM
\li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
- Uses QDate::shortMonthName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li MMMM
\li the long localized month name (e.g. 'January' to 'December').
- Uses QDate::longMonthName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li yy \li the year as two digit number (00 to 99)
\row \li yyyy \li the year as four digit number. If the year is negative,
a minus sign is prepended in addition.
@@ -829,18 +957,12 @@ QString QDate::toString(Qt::DateFormat f) const
If the datetime is invalid, an empty string will be returned.
- \warning The Qt::ISODate format is only valid for years in the
- range 0 to 9999. This restriction may apply to locale-aware
- formats as well, depending on the locale settings.
-
- \sa QDateTime::toString(), QTime::toString()
+ \sa QDateTime::toString(), QTime::toString(), QLocale::toString()
*/
QString QDate::toString(const QString& format) const
{
- if (year() > 9999)
- return QString();
- return fmtDateTime(format, 0, this);
+ return QLocale::system().toString(*this, format);
}
#endif //QT_NO_DATESTRING
@@ -1099,39 +1221,34 @@ qint64 QDate::daysTo(const QDate &d) const
English short month names (e.g. "Jan"). Although localized month
names can also be used, they depend on the user's locale settings.
*/
-QDate QDate::fromString(const QString& s, Qt::DateFormat f)
+QDate QDate::fromString(const QString& string, Qt::DateFormat format)
{
- if (s.isEmpty())
+ if (string.isEmpty())
return QDate();
- switch (f) {
- case Qt::ISODate:
- {
- int year(s.mid(0, 4).toInt());
- int month(s.mid(5, 2).toInt());
- int day(s.mid(8, 2).toInt());
- if (year && month && day)
- return QDate(year, month, day);
- }
- break;
+ switch (format) {
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
+ return QLocale::system().toDate(string, QLocale::ShortFormat);
case Qt::SystemLocaleLongDate:
- return fromString(s, QLocale::system().dateFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat));
+ return QLocale::system().toDate(string, QLocale::LongFormat);
case Qt::LocaleDate:
case Qt::DefaultLocaleShortDate:
+ return QLocale().toDate(string, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
- return fromString(s, QLocale().dateFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat));
+ return QLocale().toDate(string, QLocale::LongFormat);
+ case Qt::RFC2822Date: {
+ QDate date;
+ rfcDateImpl(string, &date);
+ return date;
+ }
default:
#ifndef QT_NO_TEXTDATE
case Qt::TextDate: {
- QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ QStringList parts = string.split(QLatin1Char(' '), QString::SkipEmptyParts);
- if (parts.count() != 4) {
+ if (parts.count() != 4)
return QDate();
- }
QString monthName = parts.at(1);
int month = -1;
@@ -1150,28 +1267,25 @@ QDate QDate::fromString(const QString& s, Qt::DateFormat f)
break;
}
}
- if (month == -1) {
+ if (month == -1)
// Month name matches neither English nor other localised name.
return QDate();
- }
}
- bool ok;
- int day = parts.at(2).toInt(&ok);
- if (!ok) {
+ bool ok = false;
+ int year = parts.at(3).toInt(&ok);
+ if (!ok)
return QDate();
- }
- int year = parts.at(3).toInt(&ok);
- if (!ok) {
+ return QDate(year, month, parts.at(2).toInt());
+ }
+#endif // QT_NO_TEXTDATE
+ case Qt::ISODate: {
+ const int year = string.mid(0, 4).toInt();
+ if (year <= 0 || year > 9999)
return QDate();
+ return QDate(year, string.mid(5, 2).toInt(), string.mid(8, 2).toInt());
}
-
- return QDate(year, month, day);
- }
-#else
- break;
-#endif
}
return QDate();
}
@@ -1190,18 +1304,18 @@ QDate QDate::fromString(const QString& s, Qt::DateFormat f)
\row \li dd \li The day as a number with a leading zero (01 to 31)
\row \li ddd
\li The abbreviated localized day name (e.g. 'Mon' to 'Sun').
- Uses QDate::shortDayName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li dddd
\li The long localized day name (e.g. 'Monday' to 'Sunday').
- Uses QDate::longDayName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li M \li The month as a number without a leading zero (1 to 12)
\row \li MM \li The month as a number with a leading zero (01 to 12)
\row \li MMM
\li The abbreviated localized month name (e.g. 'Jan' to 'Dec').
- Uses QDate::shortMonthName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li MMMM
\li The long localized month name (e.g. 'January' to 'December').
- Uses QDate::longMonthName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li yy \li The year as two digit number (00 to 99)
\row \li yyyy \li The year as four digit number. If the year is negative,
a minus sign is prepended in addition.
@@ -1474,15 +1588,15 @@ int QTime::msec() const
/*!
\overload
- Returns the time as a string. Milliseconds are not included. The
- \a format parameter determines the format of the string.
+ Returns the time as a string. The \a format parameter determines
+ the format of the string.
- If \a format is Qt::TextDate, the string format is HH:MM:SS; e.g. 1
- second before midnight would be "23:59:59".
+ If \a format is Qt::TextDate, the string format is HH:MM:SS.zzz;
+ e.g. 1 second before midnight would be "23:59:59.000".
If \a format is Qt::ISODate, the string format corresponds to the
- ISO 8601 extended specification for representations of dates,
- which is also HH:MM:SS.
+ ISO 8601 extended specification (with decimal fractions) for
+ representations of dates; also HH:MM:SS.zzz.
If the \a format is Qt::SystemLocaleShortDate or
Qt::SystemLocaleLongDate, the string format depends on the locale
@@ -1498,7 +1612,13 @@ int QTime::msec() const
QLocale::ShortFormat) or QLocale().toString(time,
QLocale::LongFormat).
+ If the \a format is Qt::RFC2822Date, the string is formatted in
+ an \l{RFC 2822} compatible way. An example of this formatting is
+ "23:59:20".
+
If the time is invalid, an empty string will be returned.
+
+ \sa QDate::toString(), QDateTime::toString()
*/
QString QTime::toString(Qt::DateFormat format) const
@@ -1509,22 +1629,25 @@ QString QTime::toString(Qt::DateFormat format) const
switch (format) {
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
+ return QLocale::system().toString(*this, QLocale::ShortFormat);
case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, format == Qt::SystemLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat);
+ return QLocale::system().toString(*this, QLocale::LongFormat);
case Qt::LocaleDate:
case Qt::DefaultLocaleShortDate:
+ return QLocale().toString(*this, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, format == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat);
-
- default:
+ return QLocale().toString(*this, QLocale::LongFormat);
+ case Qt::RFC2822Date:
+ return QString::fromLatin1("%1:%2:%3").arg(hour(), 2, 10, QLatin1Char('0'))
+ .arg(minute(), 2, 10, QLatin1Char('0'))
+ .arg(second(), 2, 10, QLatin1Char('0'));
case Qt::ISODate:
case Qt::TextDate:
- return QString::fromLatin1("%1:%2:%3")
- .arg(hour(), 2, 10, QLatin1Char('0'))
- .arg(minute(), 2, 10, QLatin1Char('0'))
- .arg(second(), 2, 10, QLatin1Char('0'));
+ default:
+ return QString::fromUtf8("%1:%2:%3.%4").arg(hour(), 2, 10, QLatin1Char('0'))
+ .arg(minute(), 2, 10, QLatin1Char('0'))
+ .arg(second(), 2, 10, QLatin1Char('0'))
+ .arg(msec(), 3, 10, QLatin1Char('0'));
}
}
@@ -1574,11 +1697,11 @@ QString QTime::toString(Qt::DateFormat format) const
If the time is invalid, an empty string will be returned.
If \a format is empty, the default format "hh:mm:ss" is used.
- \sa QDate::toString(), QDateTime::toString()
+ \sa QDate::toString(), QDateTime::toString(), QLocale::toString()
*/
QString QTime::toString(const QString& format) const
{
- return fmtDateTime(format, this, 0);
+ return QLocale::system().toString(*this, format);
}
#endif //QT_NO_DATESTRING
/*!
@@ -1759,99 +1882,68 @@ int QTime::msecsTo(const QTime &t) const
#ifndef QT_NO_DATESTRING
-// These anonymous functions tidy up QDateTime::fromString()
-// and avoid confusion of responsibility between it and QTime::fromString().
-namespace {
-inline bool isMidnight(int hour, int minute, int second, int msec)
+static QTime fromIsoTimeString(const QString &string, Qt::DateFormat format, bool *isMidnight24)
{
- return hour == 24 && minute == 0 && second == 0 && msec == 0;
-}
+ if (isMidnight24)
+ *isMidnight24 = false;
-QTime fromStringImpl(const QString &s, Qt::DateFormat f, bool &isMidnight24)
-{
- if (s.isEmpty()) {
- // Return a null time.
+ const int size = string.size();
+ if (size < 5)
return QTime();
- }
- switch (f) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- case Qt::SystemLocaleLongDate:
- {
- QLocale::FormatType formatType(Qt::SystemLocaleLongDate ? QLocale::LongFormat : QLocale::ShortFormat);
- return QTime::fromString(s, QLocale::system().timeFormat(formatType));
- }
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- case Qt::DefaultLocaleLongDate:
- {
- QLocale::FormatType formatType(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat : QLocale::ShortFormat);
- return QTime::fromString(s, QLocale().timeFormat(formatType));
- }
- case Qt::TextDate:
- case Qt::ISODate:
- {
- bool ok = true;
- const int hour(s.mid(0, 2).toInt(&ok));
- if (!ok)
+ bool ok = false;
+ int hour = string.mid(0, 2).toInt(&ok);
+ if (!ok)
+ return QTime();
+ const int minute = string.mid(3, 2).toInt(&ok);
+ if (!ok)
+ return QTime();
+ int second = 0;
+ int msec = 0;
+
+ if (size == 5) {
+ // HH:MM format
+ second = 0;
+ msec = 0;
+ } else if (string.at(5) == QLatin1Char(',') || string.at(5) == QLatin1Char('.')) {
+ if (format == Qt::TextDate)
return QTime();
- const int minute(s.mid(3, 2).toInt(&ok));
+ // ISODate HH:MM.SSSSSS format
+ // We only want 5 digits worth of fraction of minute. This follows the existing
+ // behavior that determines how milliseconds are read; 4 millisecond digits are
+ // read and then rounded to 3. If we read at most 5 digits for fraction of minute,
+ // the maximum amount of millisecond digits it will expand to once converted to
+ // seconds is 4. E.g. 12:34,99999 will expand to 12:34:59.9994. The milliseconds
+ // will then be rounded up AND clamped to 999.
+ const float minuteFraction = QString::fromUtf8("0.%1").arg(string.mid(6, 5)).toFloat(&ok);
if (!ok)
return QTime();
- if (f == Qt::ISODate) {
- if (s.size() == 5) {
- // Do not need to specify seconds if using ISO format.
- return QTime(hour, minute, 0, 0);
- } else if ((s.size() > 6) && (s[5] == QLatin1Char(',') || s[5] == QLatin1Char('.'))) {
- // Possibly specifying fraction of a minute.
-
- // We only want 5 digits worth of fraction of minute. This follows the existing
- // behaviour that determines how milliseconds are read; 4 millisecond digits are
- // read and then rounded to 3. If we read at most 5 digits for fraction of minute,
- // the maximum amount of millisecond digits it will expand to once converted to
- // seconds is 4. E.g. 12:34,99999 will expand to 12:34:59.9994. The milliseconds
- // will then be rounded up AND clamped to 999.
- const QString minuteFractionStr(QLatin1String("0.") + s.mid(6, 5));
- const float minuteFraction = minuteFractionStr.toFloat(&ok);
- if (!ok)
- return QTime();
- const float secondWithMs = minuteFraction * 60;
- const float second = std::floor(secondWithMs);
- const float millisecond = 1000 * (secondWithMs - second);
- const int millisecondRounded = qMin(qRound(millisecond), 999);
-
- if (isMidnight(hour, minute, second, millisecondRounded)) {
- isMidnight24 = true;
- return QTime(0, 0, 0, 0);
- }
-
- return QTime(hour, minute, second, millisecondRounded);
- }
- }
-
- const int second(s.mid(6, 2).toInt(&ok));
+ const float secondWithMs = minuteFraction * 60;
+ const float secondNoMs = std::floor(secondWithMs);
+ const float secondFraction = secondWithMs - secondNoMs;
+ second = secondNoMs;
+ msec = qMin(qRound(secondFraction * 1000.0), 999);
+ } else {
+ // HH:MM:SS or HH:MM:SS.sssss
+ second = string.mid(6, 2).toInt(&ok);
if (!ok)
return QTime();
- const QString msec_s(QLatin1String("0.") + s.mid(9, 4));
- const double msec(msec_s.toDouble(&ok));
- if (!ok)
- return QTime(hour, minute, second, 0);
-
- if (f == Qt::ISODate) {
- if (isMidnight(hour, minute, second, msec)) {
- isMidnight24 = true;
- return QTime(0, 0, 0, 0);
- }
+ if (size > 8 && (string.at(8) == QLatin1Char(',') || string.at(8) == QLatin1Char('.'))) {
+ const double secondFraction = QString::fromUtf8("0.%1").arg(string.mid(9, 4)).toDouble(&ok);
+ if (!ok)
+ return QTime();
+ msec = qMin(qRound(secondFraction * 1000.0), 999);
}
- return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999));
}
+
+ if (format == Qt::ISODate && hour == 24 && minute == 0 && second == 0 && msec == 0) {
+ if (isMidnight24)
+ *isMidnight24 = true;
+ hour = 0;
}
- Q_UNREACHABLE();
- return QTime();
-}
-}
+ return QTime(hour, minute, second, msec);
+}
/*!
\fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
@@ -1865,10 +1957,32 @@ QTime fromStringImpl(const QString &s, Qt::DateFormat f, bool &isMidnight24)
fails for the default locale). This should be considered an
implementation detail.
*/
-QTime QTime::fromString(const QString& s, Qt::DateFormat f)
+QTime QTime::fromString(const QString& string, Qt::DateFormat format)
{
- bool unused;
- return fromStringImpl(s, f, unused);
+ if (string.isEmpty())
+ return QTime();
+
+ switch (format) {
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ return QLocale::system().toTime(string, QLocale::ShortFormat);
+ case Qt::SystemLocaleLongDate:
+ return QLocale::system().toTime(string, QLocale::LongFormat);
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ return QLocale().toTime(string, QLocale::ShortFormat);
+ case Qt::DefaultLocaleLongDate:
+ return QLocale().toTime(string, QLocale::LongFormat);
+ case Qt::RFC2822Date: {
+ QTime time;
+ rfcDateImpl(string, 0, &time);
+ return time;
+ }
+ case Qt::ISODate:
+ case Qt::TextDate:
+ default:
+ return fromIsoTimeString(string, format, 0);
+ }
}
/*!
@@ -2129,6 +2243,20 @@ int QTime::elapsed() const
time zone before 1970, even if the system's time zone database
supports that information.
+ \section2 Offset From UTC
+
+ A Qt::TimeSpec of Qt::OffsetFromUTC is also supported. This allows you
+ to define a QDateTime relative to UTC at a fixed offset of a given number
+ of seconds from UTC. For example, an offset of +3600 seconds is one hour
+ ahead of UTC and is usually written in ISO standard notation as
+ "UTC+01:00". Daylight Savings Time never applies with this TimeSpec.
+
+ There is no explicit size restriction to the offset seconds, but there is
+ an implicit limit imposed when using the toString() and fromString()
+ methods which use a format of [+|-]hh:mm, effectively limiting the range
+ to +/- 99 hours and 59 minutes and whole minutes only. Note that currently
+ no time zone lies outside the range of +/- 14 hours.
+
\sa QDate, QTime, QDateTimeEdit
*/
@@ -2150,10 +2278,8 @@ QDateTime::QDateTime()
*/
QDateTime::QDateTime(const QDate &date)
- : d(new QDateTimePrivate)
+ : d(new QDateTimePrivate(date, QTime(0, 0, 0), Qt::LocalTime, 0))
{
- d->date = date;
- d->time = QTime(0, 0, 0);
}
/*!
@@ -2161,14 +2287,72 @@ QDateTime::QDateTime(const QDate &date)
the time specification defined by \a spec.
If \a date is valid and \a time is not, the time will be set to midnight.
+
+ If \a spec is Qt::OffsetFromUTC then it will be set to Qt::UTC, i.e. an
+ offset of 0 seconds. To create a Qt::OffsetFromUTC datetime use the
+ correct constructor.
*/
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
- : d(new QDateTimePrivate)
+ : d(new QDateTimePrivate(date, time, spec, 0))
{
- d->date = date;
- d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time;
- d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;
+}
+
+/*!
+ \since 5.2
+
+ Constructs a datetime with the given \a date and \a time, using
+ the time specification defined by \a spec and \a offsetSeconds seconds.
+
+ If \a date is valid and \a time is not, the time will be set to midnight.
+
+ If the \a spec is not Qt::OffsetFromUTC then \a offsetSeconds will be ignored.
+
+ If the \a spec is Qt::OffsetFromUTC and \a offsetSeconds is 0 then the
+ timeSpec() will be set to Qt::UTC, i.e. an offset of 0 seconds.
+*/
+
+QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds)
+ : d(new QDateTimePrivate(date, time, spec, offsetSeconds))
+{
+}
+
+/*!
+ \internal
+ \since 5.2
+
+ Private.
+
+ Create a datetime with the given \a date, \a time, \a spec and \a offsetSeconds
+*/
+
+QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec,
+ int offsetSeconds)
+{
+ date = toDate;
+
+ if (!toTime.isValid() && toDate.isValid())
+ time = QTime(0, 0, 0);
+ else
+ time = toTime;
+
+ m_offsetFromUtc = 0;
+
+ switch (toSpec) {
+ case Qt::UTC :
+ spec = QDateTimePrivate::UTC;
+ break;
+ case Qt::OffsetFromUTC :
+ if (offsetSeconds == 0) {
+ spec = QDateTimePrivate::UTC;
+ } else {
+ spec = QDateTimePrivate::OffsetFromUTC;
+ m_offsetFromUtc = offsetSeconds;
+ }
+ break;
+ case Qt::LocalTime :
+ spec = QDateTimePrivate::LocalUnknown;
+ }
}
/*!
@@ -2271,6 +2455,77 @@ Qt::TimeSpec QDateTime::timeSpec() const
}
/*!
+ \since 5.2
+
+ Returns the current Offset From UTC in seconds.
+
+ If the timeSpec() is Qt::OffsetFromUTC this will be the value originally set.
+
+ If the timeSpec() is Qt::LocalTime this will be the difference between the
+ Local Time and UTC including any Daylight Saving Offset.
+
+ If the timeSpec() is Qt::UTC this will be 0.
+
+ \sa setOffsetFromUtc()
+*/
+
+int QDateTime::offsetFromUtc() const
+{
+ switch (d->spec) {
+ case QDateTimePrivate::OffsetFromUTC:
+ return d->m_offsetFromUtc;
+ case QDateTimePrivate::UTC:
+ return 0;
+ default: // Any Qt::LocalTime
+ const QDateTime fakeDate(d->date, d->time, Qt::UTC);
+ return (fakeDate.toMSecsSinceEpoch() - toMSecsSinceEpoch()) / 1000;
+ }
+}
+
+/*!
+ \since 5.2
+
+ Returns the Time Zone Abbreviation for the datetime.
+
+ If the timeSpec() is Qt::UTC this will be "UTC".
+
+ If the timeSpec() is Qt::OffsetFromUTC this will be in the format
+ "UTC[+-]00:00".
+
+ If the timeSpec() is Qt::LocalTime then the host system is queried for the
+ correct abbreviation.
+
+ Note that abbreviations may or may not be localized.
+
+ Note too that the abbreviation is not guaranteed to be a unique value,
+ i.e. different time zones may have the same abbreviation.
+
+ \sa timeSpec()
+*/
+
+QString QDateTime::timeZoneAbbreviation() const
+{
+ switch (d->spec) {
+ case QDateTimePrivate::UTC:
+ return QStringLiteral("UTC");
+ case QDateTimePrivate::OffsetFromUTC:
+ return QLatin1String("UTC") + toOffsetString(Qt::ISODate, d->m_offsetFromUtc);
+ default: { // Any Qt::LocalTime
+#if defined(Q_OS_WINCE)
+ // TODO Stub to enable compilation on WinCE
+ return QString();
+#else
+ QDate dt = adjustDate(d->date);
+ QTime tm = d->time;
+ QString abbrev;
+ qt_mktime(&dt, &tm, 0, &abbrev, 0);
+ return abbrev;
+#endif // !Q_OS_WINCE
+ }
+ }
+}
+
+/*!
Sets the date part of this datetime to \a date.
If no time is set, it is set to midnight.
@@ -2307,6 +2562,9 @@ void QDateTime::setTime(const QTime &time)
Sets the time specification used in this datetime to \a spec.
The datetime will refer to a different point in time.
+ If \a spec is Qt::OffsetFromUTC then the timeSpec() will be set
+ to Qt::UTC, i.e. an effective offset of 0.
+
Example:
\snippet code/src_corelib_tools_qdatetime.cpp 19
@@ -2317,17 +2575,43 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec)
{
detach();
- switch(spec)
- {
- case Qt::UTC:
- d->spec = QDateTimePrivate::UTC;
- break;
- case Qt::OffsetFromUTC:
- d->spec = QDateTimePrivate::OffsetFromUTC;
- break;
- default:
- d->spec = QDateTimePrivate::LocalUnknown;
- break;
+ d->m_offsetFromUtc = 0;
+ switch (spec) {
+ case Qt::UTC:
+ case Qt::OffsetFromUTC:
+ d->spec = QDateTimePrivate::UTC;
+ break;
+ default:
+ d->spec = QDateTimePrivate::LocalUnknown;
+ break;
+ }
+}
+
+/*!
+ \since 5.2
+
+ Sets the timeSpec() to Qt::OffsetFromUTC and the offset to \a offsetSeconds.
+ The datetime will refer to a different point in time.
+
+ The maximum and minimum offset is 14 positive or negative hours. If
+ \a offsetSeconds is larger or smaller than that, then the result is
+ undefined.
+
+ If \a offsetSeconds is 0 then the timeSpec() will be set to Qt::UTC.
+
+ \sa isValid(), offsetFromUtc()
+*/
+
+void QDateTime::setOffsetFromUtc(int offsetSeconds)
+{
+ detach();
+
+ if (offsetSeconds == 0) {
+ d->spec = QDateTimePrivate::UTC;
+ d->m_offsetFromUtc = 0;
+ } else {
+ d->spec = QDateTimePrivate::OffsetFromUTC;
+ d->m_offsetFromUtc = offsetSeconds;
}
}
@@ -2410,8 +2694,6 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs)
{
detach();
- QDateTimePrivate::Spec oldSpec = d->spec;
-
qint64 ddays = msecs / MSECS_PER_DAY;
msecs %= MSECS_PER_DAY;
if (msecs < 0) {
@@ -2422,10 +2704,11 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs)
d->date = QDate(1970, 1, 1).addDays(ddays);
d->time = QTime(0, 0, 0).addMSecs(msecs);
- d->spec = QDateTimePrivate::UTC;
- if (oldSpec != QDateTimePrivate::UTC)
- d->spec = d->getLocal(d->date, d->time);
+ if (d->spec == QDateTimePrivate::OffsetFromUTC)
+ utcToOffset(&d->date, &d->time, d->m_offsetFromUtc);
+ else if (d->spec != QDateTimePrivate::UTC)
+ utcToLocal(d->date, d->time);
}
/*!
@@ -2443,14 +2726,13 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
{
detach();
- QDateTimePrivate::Spec oldSpec = d->spec;
-
d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
d->time = QTime(0, 0, 0).addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
- d->spec = QDateTimePrivate::UTC;
- if (oldSpec != QDateTimePrivate::UTC)
- d->spec = d->getLocal(d->date, d->time);
+ if (d->spec == QDateTimePrivate::OffsetFromUTC)
+ utcToOffset(&d->date, &d->time, d->m_offsetFromUtc);
+ else if (d->spec != QDateTimePrivate::UTC)
+ utcToLocal(d->date, d->time);
}
#ifndef QT_NO_DATESTRING
@@ -2464,16 +2746,17 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
If the \a format is Qt::TextDate, the string is formatted in
the default way. QDate::shortDayName(), QDate::shortMonthName(),
and QTime::toString() are used to generate the string, so the
- day and month names will be localized names. An example of this
- formatting is "Wed May 20 03:40:13 1998".
+ day and month names will be localized names using the system locale,
+ i.e. QLocale::system(). An example of this formatting is
+ "Wed May 20 03:40:13.456 1998".
If the \a format is Qt::ISODate, the string format corresponds
- to the ISO 8601 extended specification for representations of
- dates and times, taking the form YYYY-MM-DDTHH:MM:SS[Z|[+|-]HH:MM],
- depending on the timeSpec() of the QDateTime. If the timeSpec()
- is Qt::UTC, Z will be appended to the string; if the timeSpec() is
- Qt::OffsetFromUTC, the offset in hours and minutes from UTC will
- be appended to the string.
+ to the ISO 8601 extended specification (with decimal fractions) for
+ representations of dates and times, taking the form
+ YYYY-MM-DDTHH:MM:SS.zzz[Z|[+|-]HH:MM], depending on the timeSpec()
+ of the QDateTime. If the timeSpec() is Qt::UTC, Z will be appended
+ to the string; if the timeSpec() is Qt::OffsetFromUTC, the offset
+ in hours and minutes from UTC will be appended to the string.
If the \a format is Qt::SystemLocaleShortDate or
Qt::SystemLocaleLongDate, the string format depends on the locale
@@ -2489,6 +2772,9 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
QLocale::ShortFormat) or QLocale().toString(datetime,
QLocale::LongFormat).
+ If the \a format is Qt::RFC2822Date, the string is formatted
+ following \l{RFC 2822}.
+
If the datetime is invalid, an empty string will be returned.
\warning The Qt::ISODate format is only valid for years in the
@@ -2498,13 +2784,64 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
\sa QDate::toString(), QTime::toString(), Qt::DateFormat
*/
-QString QDateTime::toString(Qt::DateFormat f) const
+QString QDateTime::toString(Qt::DateFormat format) const
{
QString buf;
if (!isValid())
return buf;
- if (f == Qt::ISODate) {
+ switch (format) {
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ return QLocale::system().toString(*this, QLocale::ShortFormat);
+ case Qt::SystemLocaleLongDate:
+ return QLocale::system().toString(*this, QLocale::LongFormat);
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ return QLocale().toString(*this, QLocale::ShortFormat);
+ case Qt::DefaultLocaleLongDate:
+ return QLocale().toString(*this, QLocale::LongFormat);
+ case Qt::RFC2822Date: {
+ buf = toString(QStringLiteral("dd MMM yyyy hh:mm:ss "));
+
+ int utcOffset = d->m_offsetFromUtc;
+ if (timeSpec() == Qt::LocalTime) {
+ QDateTime utc = toUTC();
+ utc.setTimeSpec(timeSpec());
+ utcOffset = utc.secsTo(*this);
+ }
+
+ const int offset = qAbs(utcOffset);
+ buf += QLatin1Char((offset == utcOffset) ? '+' : '-');
+
+ const int hour = offset / 3600;
+ if (hour < 10)
+ buf += QLatin1Char('0');
+ buf += QString::number(hour);
+
+ const int min = (offset - (hour * 3600)) / 60;
+ if (min < 10)
+ buf += QLatin1Char('0');
+ buf += QString::number(min);
+ return buf;
+ }
+ default:
+#ifndef QT_NO_TEXTDATE
+ case Qt::TextDate:
+ //We cant use date.toString(Qt::TextDate) as we need to insert the time before the year
+ buf = QString::fromUtf8("%1 %2 %3 %4 %5").arg(d->date.shortDayName(d->date.dayOfWeek()))
+ .arg(d->date.shortMonthName(d->date.month()))
+ .arg(d->date.day())
+ .arg(d->time.toString(Qt::TextDate))
+ .arg(d->date.year());
+ if (timeSpec() != Qt::LocalTime) {
+ buf += QStringLiteral(" GMT");
+ if (d->spec == QDateTimePrivate::OffsetFromUTC)
+ buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc);
+ }
+ return buf;
+#endif
+ case Qt::ISODate:
buf = d->date.toString(Qt::ISODate);
if (buf.isEmpty())
return QString(); // failed to convert
@@ -2514,61 +2851,14 @@ QString QDateTime::toString(Qt::DateFormat f) const
case QDateTimePrivate::UTC:
buf += QLatin1Char('Z');
break;
- case QDateTimePrivate::OffsetFromUTC: {
- int sign = d->utcOffset >= 0 ? 1: -1;
- buf += QString::fromLatin1("%1%2:%3").
- arg(sign == 1 ? QLatin1Char('+') : QLatin1Char('-')).
- arg(d->utcOffset * sign / SECS_PER_HOUR, 2, 10, QLatin1Char('0')).
- arg((d->utcOffset / 60) % 60, 2, 10, QLatin1Char('0'));
+ case QDateTimePrivate::OffsetFromUTC:
+ buf += toOffsetString(Qt::ISODate, d->m_offsetFromUtc);
break;
- }
default:
break;
}
+ return buf;
}
-#ifndef QT_NO_TEXTDATE
- else if (f == Qt::TextDate) {
-#ifndef Q_OS_WIN
- buf = d->date.shortDayName(d->date.dayOfWeek());
- buf += QLatin1Char(' ');
- buf += d->date.shortMonthName(d->date.month());
- buf += QLatin1Char(' ');
- buf += QString::number(d->date.day());
-#else
- wchar_t out[255];
- GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);
- QString winstr = QString::fromWCharArray(out);
- switch (winstr.toInt()) {
- case 1:
- buf = d->date.shortDayName(d->date.dayOfWeek());
- buf += QLatin1Char(' ');
- buf += QString::number(d->date.day());
- buf += QLatin1String(". ");
- buf += d->date.shortMonthName(d->date.month());
- break;
- default:
- buf = d->date.shortDayName(d->date.dayOfWeek());
- buf += QLatin1Char(' ');
- buf += d->date.shortMonthName(d->date.month());
- buf += QLatin1Char(' ');
- buf += QString::number(d->date.day());
- }
-#endif
- buf += QLatin1Char(' ');
- buf += d->time.toString();
- buf += QLatin1Char(' ');
- buf += QString::number(d->date.year());
- }
-#endif
- else {
- buf = d->date.toString(f);
- if (buf.isEmpty())
- return QString(); // failed to convert
- buf += QLatin1Char(' ');
- buf += d->time.toString(f);
- }
-
- return buf;
}
/*!
@@ -2583,18 +2873,18 @@ QString QDateTime::toString(Qt::DateFormat f) const
\row \li dd \li the day as number with a leading zero (01 to 31)
\row \li ddd
\li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
- Uses QDate::shortDayName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li dddd
\li the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
- Uses QDate::longDayName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li M \li the month as number without a leading zero (1-12)
\row \li MM \li the month as number with a leading zero (01-12)
\row \li MMM
\li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
- Uses QDate::shortMonthName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li MMMM
\li the long localized month name (e.g. 'January' to 'December').
- Uses QDate::longMonthName().
+ Uses the system locale to localize the name, i.e. QLocale::system().
\row \li yy \li the year as two digit number (00-99)
\row \li yyyy \li the year as four digit number
\endtable
@@ -2607,16 +2897,21 @@ QString QDateTime::toString(Qt::DateFormat f) const
\li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
\row \li hh
\li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li H
+ \li the hour without a leading zero (0 to 23, even with AM/PM display)
+ \row \li HH
+ \li the hour with a leading zero (00 to 23, even with AM/PM display)
\row \li m \li the minute without a leading zero (0 to 59)
\row \li mm \li the minute with a leading zero (00 to 59)
\row \li s \li the second without a leading zero (0 to 59)
\row \li ss \li the second with a leading zero (00 to 59)
\row \li z \li the milliseconds without leading zeroes (0 to 999)
\row \li zzz \li the milliseconds with leading zeroes (000 to 999)
- \row \li AP
- \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
- \row \li ap
- \li use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \row \li AP or A
+ \li use AM/PM display. \e A/AP will be replaced by either "AM" or "PM".
+ \row \li ap or a
+ \li use am/pm display. \e a/ap will be replaced by either "am" or "pm".
+ \row \li t \li the timezone (for example "CEST")
\endtable
All other input characters will be ignored. Any sequence of characters that
@@ -2637,11 +2932,11 @@ QString QDateTime::toString(Qt::DateFormat f) const
If the datetime is invalid, an empty string will be returned.
- \sa QDate::toString(), QTime::toString()
+ \sa QDate::toString(), QTime::toString(), QLocale::toString()
*/
QString QDateTime::toString(const QString& format) const
{
- return fmtDateTime(format, &d->time, &d->date);
+ return QLocale::system().toString(*this, format);
}
#endif //QT_NO_DATESTRING
@@ -2655,7 +2950,10 @@ QString QDateTime::toString(const QString& format) const
QDateTime QDateTime::addDays(qint64 ndays) const
{
- return QDateTime(d->date.addDays(ndays), d->time, timeSpec());
+ QDateTime dt(*this);
+ dt.detach();
+ dt.d->date = d->date.addDays(ndays);
+ return dt;
}
/*!
@@ -2668,7 +2966,10 @@ QDateTime QDateTime::addDays(qint64 ndays) const
QDateTime QDateTime::addMonths(int nmonths) const
{
- return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());
+ QDateTime dt(*this);
+ dt.detach();
+ dt.d->date = d->date.addMonths(nmonths);
+ return dt;
}
/*!
@@ -2681,7 +2982,10 @@ QDateTime QDateTime::addMonths(int nmonths) const
QDateTime QDateTime::addYears(int nyears) const
{
- return QDateTime(d->date.addYears(nyears), d->time, timeSpec());
+ QDateTime dt(*this);
+ dt.detach();
+ dt.d->date = d->date.addYears(nyears);
+ return dt;
}
QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)
@@ -2692,10 +2996,13 @@ QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)
QDate utcDate;
QTime utcTime;
dt.d->getUTC(utcDate, utcTime);
-
addMSecs(utcDate, utcTime, msecs);
+ QDateTime utc(utcDate, utcTime, Qt::UTC);
- return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec());
+ if (dt.timeSpec() == Qt::OffsetFromUTC)
+ return utc.toOffsetFromUtc(dt.d->m_offsetFromUtc);
+ else
+ return utc.toTimeSpec(dt.timeSpec());
}
/*!
@@ -2846,12 +3153,14 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
+ static_cast<qint64>(selfTime.msecsTo(otherTime));
}
-
/*!
- \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const
+ \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
Returns a copy of this datetime converted to the given time
- \a specification.
+ \a spec.
+
+ If \a spec is Qt::OffsetFromUTC then it is set to Qt::UTC. To set to a
+ spec of Qt::OffsetFromUTC use toOffsetFromUtc().
Example:
\snippet code/src_corelib_tools_qdatetime.cpp 16
@@ -2861,19 +3170,41 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
{
- if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))
- return *this;
+ if (spec == Qt::UTC || spec == Qt::OffsetFromUTC) {
+ QDate date;
+ QTime time;
+ d->getUTC(date, time);
+ return QDateTime(date, time, Qt::UTC, 0);
+ }
QDateTime ret;
- if (spec == Qt::UTC) {
- d->getUTC(ret.d->date, ret.d->time);
- ret.d->spec = QDateTimePrivate::UTC;
- } else {
- ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
- }
+ ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
return ret;
}
+
+/*!
+ \since 5.2
+
+ \fn QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
+
+ Returns a copy of this datetime converted to a spec of Qt::OffsetFromUTC
+ with the given \a offsetSeconds.
+
+ If the \a offsetSeconds equals 0 then a UTC datetime will be returned
+
+ \sa setOffsetFromUtc(), offsetFromUtc(), toTimeSpec()
+*/
+
+QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
+{
+ QDate date;
+ QTime time;
+ d->getUTC(date, time);
+ d->addMSecs(date, time, offsetSeconds * 1000);
+ return QDateTime(date, time, Qt::OffsetFromUTC, offsetSeconds);
+}
+
/*!
Returns true if this datetime is equal to the \a other datetime;
otherwise returns false.
@@ -2883,7 +3214,7 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
bool QDateTime::operator==(const QDateTime &other) const
{
- if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset)
+ if (d->spec == other.d->spec && d->m_offsetFromUtc == other.d->m_offsetFromUtc)
return d->time == other.d->time && d->date == other.d->date;
else {
QDate date1, date2;
@@ -3160,16 +3491,32 @@ qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW
Returns a datetime whose date and time are the number of \a seconds
that have passed since 1970-01-01T00:00:00, Coordinated Universal
- Time (Qt::UTC). On systems that do not support time zones, the time
- will be set as if local time were Qt::UTC.
+ Time (Qt::UTC) and converted to Qt::LocalTime. On systems that do not
+ support time zones, the time will be set as if local time were Qt::UTC.
\sa toTime_t(), setTime_t()
*/
QDateTime QDateTime::fromTime_t(uint seconds)
{
- QDateTime d;
- d.setTime_t(seconds);
- return d;
+ return fromMSecsSinceEpoch((qint64)seconds * 1000, Qt::LocalTime);
+}
+
+/*!
+ \since 5.2
+
+ Returns a datetime whose date and time are the number of \a seconds
+ that have passed since 1970-01-01T00:00:00, Coordinated Universal
+ Time (Qt::UTC) and converted to the given \a spec.
+
+ If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be
+ ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0
+ then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds.
+
+ \sa toTime_t(), setTime_t()
+*/
+QDateTime QDateTime::fromTime_t(uint seconds, Qt::TimeSpec spec, int offsetSeconds)
+{
+ return fromMSecsSinceEpoch((qint64)seconds * 1000, spec, offsetSeconds);
}
/*!
@@ -3177,8 +3524,8 @@ QDateTime QDateTime::fromTime_t(uint seconds)
Returns a datetime whose date and time are the number of milliseconds, \a msecs,
that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
- Time (Qt::UTC). On systems that do not support time zones, the time
- will be set as if local time were Qt::UTC.
+ Time (Qt::UTC), and converted to Qt::LocalTime. On systems that do not
+ support time zones, the time will be set as if local time were Qt::UTC.
Note that there are possible values for \a msecs that lie outside the valid
range of QDateTime, both negative and positive. The behavior of this
@@ -3188,67 +3535,79 @@ QDateTime QDateTime::fromTime_t(uint seconds)
*/
QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
{
- QDateTime d;
- d.setMSecsSinceEpoch(msecs);
- return d;
+ return fromMSecsSinceEpoch(msecs, Qt::LocalTime);
}
/*!
- \since 4.4
- \internal
+ \since 5.2
- Sets the offset from UTC to \a seconds, and also sets timeSpec() to
- Qt::OffsetFromUTC.
+ Returns a datetime whose date and time are the number of milliseconds \a msecs
+ that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
+ Time (Qt::UTC) and converted to the given \a spec.
- The maximum and minimum offset is 14 positive or negative hours. If
- \a seconds is larger or smaller than that, the result is undefined.
+ Note that there are possible values for \a msecs that lie outside the valid
+ range of QDateTime, both negative and positive. The behavior of this
+ function is undefined for those values.
- 0 as offset is identical to UTC. Therefore, if \a seconds is 0, the
- timeSpec() will be set to Qt::UTC. Hence the UTC offset always
- relates to UTC, and can never relate to local time.
+ If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be
+ ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0
+ then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds.
- \sa isValid(), utcOffset()
- */
-void QDateTime::setUtcOffset(int seconds)
+ \sa fromTime_t()
+*/
+QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetSeconds)
{
- detach();
-
- /* The motivation to also setting d->spec is to ensure that the QDateTime
- * instance stays in well-defined states all the time; instead of that,
- * we instruct the user to ensure it. */
- if(seconds == 0)
- d->spec = QDateTimePrivate::UTC;
- else
- d->spec = QDateTimePrivate::OffsetFromUTC;
+ QDate newDate = QDate(1970, 1, 1);
+ QTime newTime = QTime(0, 0, 0);
+ QDateTimePrivate::addMSecs(newDate, newTime, msecs);
- /* Even if seconds is 0 we assign it to utcOffset. */
- d->utcOffset = seconds;
+ switch (spec) {
+ case Qt::UTC:
+ return QDateTime(newDate, newTime, Qt::UTC);
+ case Qt::OffsetFromUTC:
+ utcToOffset(&newDate, &newTime, offsetSeconds);
+ return QDateTime(newDate, newTime, Qt::OffsetFromUTC, offsetSeconds);
+ default:
+ utcToLocal(newDate, newTime);
+ return QDateTime(newDate, newTime, Qt::LocalTime);
+ }
}
+#if QT_DEPRECATED_SINCE(5, 2)
/*!
- \since 4.4
- \internal
-
- Returns the UTC offset in seconds. If the timeSpec() isn't
- Qt::OffsetFromUTC, 0 is returned. However, since 0 is a valid UTC
- offset, the return value of this function cannot be used to determine
- whether a utcOffset() is used or is valid; in that case, timeSpec() must be
- checked.
+ \since 4.4
+ \internal
+ \obsolete
- Likewise, if this QDateTime() is invalid or if timeSpec() isn't
- Qt::OffsetFromUTC, 0 is returned.
+ This method was added in 4.4 but never documented as public. It was replaced
+ in 5.2 with public method setOffsetFromUtc() for consistency with QTimeZone.
- The UTC offset only applies if the timeSpec() is Qt::OffsetFromUTC.
+ This method should never be made public.
- \sa isValid(), setUtcOffset()
+ \sa setOffsetFromUtc()
*/
+void QDateTime::setUtcOffset(int seconds)
+{
+ setOffsetFromUtc(seconds);
+}
+
+/*!
+ \since 4.4
+ \internal
+ \obsolete
+
+ This method was added in 4.4 but never documented as public. It was replaced
+ in 5.1 with public method offsetFromUTC() for consistency with QTimeZone.
+
+ This method should never be made public.
+
+ \sa offsetFromUTC()
+*/
int QDateTime::utcOffset() const
{
- if(isValid() && d->spec == QDateTimePrivate::OffsetFromUTC)
- return d->utcOffset;
- else
- return 0;
+ return offsetFromUtc();
}
+#endif // QT_DEPRECATED_SINCE
#ifndef QT_NO_DATESTRING
@@ -3277,144 +3636,169 @@ static int fromShortMonthName(const QString &monthName)
English short month names (e.g. "Jan"). Although localized month
names can also be used, they depend on the user's locale settings.
*/
-QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
+QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format)
{
- if (s.isEmpty()) {
+ if (string.isEmpty())
return QDateTime();
- }
- switch (f) {
+ switch (format) {
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ return QLocale::system().toDateTime(string, QLocale::ShortFormat);
+ case Qt::SystemLocaleLongDate:
+ return QLocale::system().toDateTime(string, QLocale::LongFormat);
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ return QLocale().toDateTime(string, QLocale::ShortFormat);
+ case Qt::DefaultLocaleLongDate:
+ return QLocale().toDateTime(string, QLocale::LongFormat);
+ case Qt::RFC2822Date: {
+ QDate date;
+ QTime time;
+ int utcOffset = 0;
+ rfcDateImpl(string, &date, &time, &utcOffset);
+
+ if (!date.isValid() || !time.isValid())
+ return QDateTime();
+
+ QDateTime dateTime(date, time, Qt::UTC);
+ dateTime.setOffsetFromUtc(utcOffset);
+ return dateTime;
+ }
case Qt::ISODate: {
- QString tmp = s;
- Qt::TimeSpec ts = Qt::LocalTime;
- QDate date = QDate::fromString(tmp.left(10), Qt::ISODate);
- if (tmp.size() == 10)
- return QDateTime(date);
+ const int size = string.size();
+ if (size < 10)
+ return QDateTime();
- tmp = tmp.mid(11);
+ QString isoString = string;
+ Qt::TimeSpec spec = Qt::LocalTime;
- // Recognize UTC specifications
- if (tmp.endsWith(QLatin1Char('Z'))) {
- ts = Qt::UTC;
- tmp.chop(1);
- }
+ QDate date = QDate::fromString(isoString.left(10), Qt::ISODate);
+ if (!date.isValid())
+ return QDateTime();
+ if (size == 10)
+ return QDateTime(date);
- // Recognize timezone specifications
- QRegExp rx(QLatin1String("[+-]"));
- if (tmp.contains(rx)) {
- int idx = tmp.indexOf(rx);
- QString tmp2 = tmp.mid(idx);
- tmp = tmp.left(idx);
- bool ok = true;
- int ntzhour = 1;
- int ntzminute = 3;
- if ( tmp2.indexOf(QLatin1Char(':')) == 3 )
- ntzminute = 4;
- const int tzhour(tmp2.mid(ntzhour, 2).toInt(&ok));
- const int tzminute(tmp2.mid(ntzminute, 2).toInt(&ok));
- QTime tzt(tzhour, tzminute);
- int utcOffset = (tzt.hour() * 60 + tzt.minute()) * 60;
- if ( utcOffset != 0 ) {
- ts = Qt::OffsetFromUTC;
- QDateTime dt(date, QTime::fromString(tmp, Qt::ISODate), ts);
- dt.setUtcOffset( utcOffset * (tmp2.startsWith(QLatin1Char('-')) ? -1 : 1) );
- return dt;
+ isoString.remove(0, 11);
+ int offset = 0;
+ // Check end of string for Time Zone definition, either Z for UTC or [+-]HH:MM for Offset
+ if (isoString.endsWith(QLatin1Char('Z'))) {
+ spec = Qt::UTC;
+ isoString.chop(1);
+ } else {
+ const int signIndex = isoString.indexOf(QRegExp(QStringLiteral("[+-]")));
+ if (signIndex >= 0) {
+ bool ok;
+ offset = fromOffsetString(isoString.mid(signIndex), &ok);
+ if (!ok)
+ return QDateTime();
+ isoString = isoString.left(signIndex);
+ spec = Qt::OffsetFromUTC;
}
}
- bool isMidnight24 = false;
// Might be end of day (24:00, including variants), which QTime considers invalid.
- QTime time(fromStringImpl(tmp, Qt::ISODate, isMidnight24));
- if (isMidnight24) {
- // ISO 8601 (section 4.2.3) says that 24:00 is equivalent to 00:00 the next day.
+ // ISO 8601 (section 4.2.3) says that 24:00 is equivalent to 00:00 the next day.
+ bool isMidnight24 = false;
+ QTime time = fromIsoTimeString(isoString, Qt::ISODate, &isMidnight24);
+ if (!time.isValid())
+ return QDateTime();
+ if (isMidnight24)
date = date.addDays(1);
- }
-
- return QDateTime(date, time, ts);
+ return QDateTime(date, time, spec, offset);
}
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- case Qt::SystemLocaleLongDate:
- return fromString(s, QLocale::system().dateTimeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat));
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- case Qt::DefaultLocaleLongDate:
- return fromString(s, QLocale().dateTimeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
- : QLocale::ShortFormat));
#if !defined(QT_NO_TEXTDATE)
case Qt::TextDate: {
- QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ QStringList parts = string.split(QLatin1Char(' '), QString::SkipEmptyParts);
- if ((parts.count() < 5) || (parts.count() > 6)) {
+ if ((parts.count() < 5) || (parts.count() > 6))
return QDateTime();
- }
// Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
- int month = -1, day = -1;
- bool ok;
+ int month = 0;
+ int day = 0;
+ bool ok = false;
+ // First try month then day
month = fromShortMonthName(parts.at(1));
- if (month != -1) {
- day = parts.at(2).toInt(&ok);
- if (!ok)
- day = -1;
- }
+ if (month)
+ day = parts.at(2).toInt();
- if (month == -1 || day == -1) {
- // first variant failed, lets try the other
+ // If failed try day then month
+ if (!month || !day) {
month = fromShortMonthName(parts.at(2));
- if (month != -1) {
+ if (month) {
QString dayStr = parts.at(1);
if (dayStr.endsWith(QLatin1Char('.'))) {
dayStr.chop(1);
- day = dayStr.toInt(&ok);
- if (!ok)
- day = -1;
- } else {
- day = -1;
+ day = dayStr.toInt();
}
}
}
- if (month == -1 || day == -1) {
- // both variants failed, give up
+ // If both failed, give up
+ if (!month || !day)
return QDateTime();
- }
- int year;
- QStringList timeParts = parts.at(3).split(QLatin1Char(':'));
- if ((timeParts.count() == 3) || (timeParts.count() == 2)) {
- // Year is after time, e.g. "Sun Dec 1 13:02:00 1974"
- year = parts.at(4).toInt(&ok);
- if (!ok)
- return QDateTime();
- } else { // Year is before time, e.g. "Sun Dec 1 1974 13:02:00"
- timeParts = parts.at(4).split(QLatin1Char(':'));
- if ((timeParts.count() != 3) && (timeParts.count() != 2))
- return QDateTime();
- year = parts.at(3).toInt(&ok);
- if (!ok)
- return QDateTime();
+ // Year can be before or after time, "Sun Dec 1 1974 13:02:00" or "Sun Dec 1 13:02:00 1974"
+ // Guess which by looking for ':' in the time
+ int year = 0;
+ int yearPart = 0;
+ int timePart = 0;
+ if (parts.at(3).contains(QLatin1Char(':'))) {
+ yearPart = 4;
+ timePart = 3;
+ } else if (parts.at(4).contains(QLatin1Char(':'))) {
+ yearPart = 3;
+ timePart = 4;
+ } else {
+ return QDateTime();
}
+ year = parts.at(yearPart).toInt(&ok);
+ if (!ok)
+ return QDateTime();
+
+ QDate date(year, month, day);
+ if (!date.isValid())
+ return QDateTime();
+
+ QStringList timeParts = parts.at(timePart).split(QLatin1Char(':'));
+ if (timeParts.count() < 2 || timeParts.count() > 3)
+ return QDateTime();
+
int hour = timeParts.at(0).toInt(&ok);
- if (!ok) {
+ if (!ok)
return QDateTime();
- }
int minute = timeParts.at(1).toInt(&ok);
- if (!ok) {
+ if (!ok)
return QDateTime();
- }
- int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;
- if (!ok) {
- return QDateTime();
+ int second = 0;
+ int millisecond = 0;
+ if (timeParts.count() > 2) {
+ QStringList secondParts = timeParts.at(2).split(QLatin1Char('.'));
+ if (secondParts.size() > 2) {
+ return QDateTime();
+ }
+
+ second = secondParts.first().toInt(&ok);
+ if (!ok) {
+ return QDateTime();
+ }
+
+ if (secondParts.size() > 1) {
+ millisecond = secondParts.last().toInt(&ok);
+ if (!ok) {
+ return QDateTime();
+ }
+ }
}
- QDate date(year, month, day);
- QTime time(hour, minute, second);
+ QTime time(hour, minute, second, millisecond);
+ if (!time.isValid())
+ return QDateTime();
if (parts.count() == 5)
return QDateTime(date, time, Qt::LocalTime);
@@ -3422,26 +3806,15 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
QString tz = parts.at(5);
if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
return QDateTime();
- QDateTime dt(date, time, Qt::UTC);
- if (tz.length() > 3) {
- int tzoffset = 0;
- QChar sign = tz.at(3);
- if ((sign != QLatin1Char('+'))
- && (sign != QLatin1Char('-'))) {
- return QDateTime();
- }
- int tzhour = tz.mid(4, 2).toInt(&ok);
- if (!ok)
- return QDateTime();
- int tzminute = tz.mid(6).toInt(&ok);
+ tz.remove(0, 3);
+ if (!tz.isEmpty()) {
+ int offset = fromOffsetString(tz, &ok);
if (!ok)
return QDateTime();
- tzoffset = (tzhour*60 + tzminute) * 60;
- if (sign == QLatin1Char('-'))
- tzoffset = -tzoffset;
- dt.setUtcOffset(tzoffset);
+ return QDateTime(date, time, Qt::OffsetFromUTC, offset);
+ } else {
+ return QDateTime(date, time, Qt::UTC);
}
- return dt.toLocalTime();
}
#endif //QT_NO_TEXTDATE
}
@@ -3691,7 +4064,7 @@ QDataStream &operator>>(QDataStream &in, QTime &time)
*/
QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
{
- if (out.version() == 13) {
+ if (out.version() == QDataStream::Qt_5_0) {
if (dateTime.isValid()) {
// This approach is wrong and should not be used again; it breaks
// the guarantee that a deserialised local datetime is the same time
@@ -3704,8 +4077,12 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
out << (qint8)dateTime.timeSpec();
} else {
out << dateTime.d->date << dateTime.d->time;
- if (out.version() >= 7)
+ if (out.version() >= QDataStream::Qt_4_0)
out << (qint8)dateTime.d->spec;
+ if (out.version() >= QDataStream::Qt_5_2
+ && dateTime.d->spec == QDateTimePrivate::OffsetFromUTC) {
+ out << qint32(dateTime.offsetFromUtc());
+ }
}
return out;
}
@@ -3724,220 +4101,98 @@ QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
in >> dateTime.d->date >> dateTime.d->time;
- if (in.version() == 13) {
+ if (in.version() == QDataStream::Qt_5_0) {
qint8 ts = 0;
in >> ts;
if (dateTime.isValid()) {
- // We always store the datetime as UTC in 13 onwards.
+ // We incorrectly stored the datetime as UTC in Qt_5_0.
dateTime.d->spec = QDateTimePrivate::UTC;
dateTime = dateTime.toTimeSpec(static_cast<Qt::TimeSpec>(ts));
}
} else {
qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
- if (in.version() >= 7)
+ if (in.version() >= QDataStream::Qt_4_0)
in >> ts;
+ qint32 offset = 0;
+ if (in.version() >= QDataStream::Qt_5_2 && ts == qint8(QDateTimePrivate::OffsetFromUTC))
+ in >> offset;
dateTime.d->spec = (QDateTimePrivate::Spec)ts;
+ dateTime.d->m_offsetFromUtc = offset;
}
return in;
}
#endif // QT_NO_DATASTREAM
-
-// checks if there is an unquoted 'AP' or 'ap' in the string
-static bool hasUnquotedAP(const QString &f)
-{
- const QLatin1Char quote('\'');
- bool inquote = false;
- const int max = f.size();
- for (int i=0; i<max; ++i) {
- if (f.at(i) == quote) {
- inquote = !inquote;
- } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
- return true;
- }
- }
- return false;
-}
-
-#ifndef QT_NO_DATESTRING
/*****************************************************************************
Some static function used by QDate, QTime and QDateTime
*****************************************************************************/
-// Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
-static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
-{
- if (f.isEmpty())
- return QString();
-
- QString buf = f;
- int removed = 0;
-
- if (dt) {
- if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {
- const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
- if (hour12 && dt->hour() > 12)
- buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
- else if (hour12 && dt->hour() == 0)
- buf = QLatin1String("12");
- else
- buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
- removed = 2;
- } else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {
- const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
- if (hour12 && dt->hour() > 12)
- buf = QString::number(dt->hour() - 12);
- else if (hour12 && dt->hour() == 0)
- buf = QLatin1String("12");
- else
- buf = QString::number(dt->hour());
- removed = 1;
- } else if (f.startsWith(QLatin1String("mm"))) {
- buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
- removed = 2;
- } else if (f.at(0) == (QLatin1Char('m'))) {
- buf = QString::number(dt->minute());
- removed = 1;
- } else if (f.startsWith(QLatin1String("ss"))) {
- buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
- removed = 2;
- } else if (f.at(0) == QLatin1Char('s')) {
- buf = QString::number(dt->second());
- } else if (f.startsWith(QLatin1String("zzz"))) {
- buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
- removed = 3;
- } else if (f.at(0) == QLatin1Char('z')) {
- buf = QString::number(dt->msec());
- removed = 1;
- } else if (f.at(0).toUpper() == QLatin1Char('A')) {
- const bool upper = f.at(0) == QLatin1Char('A');
- buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
- if (upper)
- buf = buf.toUpper();
- if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&
- f.at(0).isUpper() == f.at(1).isUpper()) {
- removed = 2;
- } else {
- removed = 1;
- }
+#ifndef QT_NO_DATESTRING
+static void rfcDateImpl(const QString &s, QDate *dd, QTime *dt, int *utcOffset)
+{
+ int day = -1;
+ int month = -1;
+ int year = -1;
+ int hour = -1;
+ int min = -1;
+ int sec = -1;
+ int hourOffset = 0;
+ int minOffset = 0;
+ bool positiveOffset = false;
+
+ // Matches "Wdy, DD Mon YYYY HH:MM:SS ±hhmm" (Wdy, being optional)
+ QRegExp rex(QStringLiteral("^(?:[A-Z][a-z]+,)?[ \\t]*(\\d{1,2})[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d)(?::(\\d\\d))?)?[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
+ if (s.indexOf(rex) == 0) {
+ if (dd) {
+ day = rex.cap(1).toInt();
+ month = qt_monthNumberFromShortName(rex.cap(2));
+ year = rex.cap(3).toInt();
}
- }
-
- if (dd) {
- if (f.startsWith(QLatin1String("dddd"))) {
- buf = dd->longDayName(dd->dayOfWeek());
- removed = 4;
- } else if (f.startsWith(QLatin1String("ddd"))) {
- buf = dd->shortDayName(dd->dayOfWeek());
- removed = 3;
- } else if (f.startsWith(QLatin1String("dd"))) {
- buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
- removed = 2;
- } else if (f.at(0) == QLatin1Char('d')) {
- buf = QString::number(dd->day());
- removed = 1;
- } else if (f.startsWith(QLatin1String("MMMM"))) {
- buf = dd->longMonthName(dd->month());
- removed = 4;
- } else if (f.startsWith(QLatin1String("MMM"))) {
- buf = dd->shortMonthName(dd->month());
- removed = 3;
- } else if (f.startsWith(QLatin1String("MM"))) {
- buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
- removed = 2;
- } else if (f.at(0) == QLatin1Char('M')) {
- buf = QString::number(dd->month());
- removed = 1;
- } else if (f.startsWith(QLatin1String("yyyy"))) {
- const int year = dd->year();
- buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));
- if(year > 0)
- removed = 4;
- else
- {
- buf.prepend(QLatin1Char('-'));
- removed = 5;
+ if (dt) {
+ if (!rex.cap(4).isEmpty()) {
+ hour = rex.cap(4).toInt();
+ min = rex.cap(5).toInt();
+ sec = rex.cap(6).toInt();
}
-
- } else if (f.startsWith(QLatin1String("yy"))) {
- buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));
- removed = 2;
+ positiveOffset = (rex.cap(7) == QStringLiteral("+"));
+ hourOffset = rex.cap(8).toInt();
+ minOffset = rex.cap(9).toInt();
}
- }
- if (removed == 0 || removed >= f.size()) {
- return buf;
- }
-
- return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
-}
-
-// Parses the format string and uses getFmtString to get the values for the tokens. Ret
-static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
-{
- QString buf;
-
- if (f.isEmpty())
- return buf;
- if (dt && !dt->isValid())
- return buf;
- if (dd && !dd->isValid())
- return buf;
-
- const bool ap = hasUnquotedAP(f);
-
- QString frm;
- uint status = '0';
-
- for (int i = 0, n = f.length(); i < n; ++i) {
- const QChar c = f.at(i);
- const uint cc = c.unicode();
- if (cc == '\'') {
- if (status == cc) {
- if (i > 0 && f.at(i - 1).unicode() == cc)
- buf += c;
- status = '0';
- } else {
- if (!frm.isEmpty()) {
- buf += getFmtString(frm, dt, dd, ap);
- frm.clear();
- }
- status = cc;
+ if (utcOffset)
+ *utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60));
+ } else {
+ // Matches "Wdy Mon DD HH:MM:SS YYYY"
+ QRegExp rex(QStringLiteral("^[A-Z][a-z]+[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d):(\\d\\d))?[ \\t]+(\\d\\d\\d\\d)[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
+ if (s.indexOf(rex) == 0) {
+ if (dd) {
+ month = qt_monthNumberFromShortName(rex.cap(1));
+ day = rex.cap(2).toInt();
+ year = rex.cap(6).toInt();
}
- } else if (status == '\'') {
- buf += c;
- } else if (c == status) {
- if (ap && (cc == 'P' || cc == 'p'))
- status = '0';
- frm += c;
- } else {
- buf += getFmtString(frm, dt, dd, ap);
- frm.clear();
- if (cc == 'h' || cc == 'm' || cc == 'H' || cc == 's' || cc == 'z') {
- status = cc;
- frm += c;
- } else if (cc == 'd' || cc == 'M' || cc == 'y') {
- status = cc;
- frm += c;
- } else if (ap && cc == 'A') {
- status = 'P';
- frm += c;
- } else if (ap && cc == 'a') {
- status = 'p';
- frm += c;
- } else {
- buf += c;
- status = '0';
+ if (dt) {
+ if (!rex.cap(3).isEmpty()) {
+ hour = rex.cap(3).toInt();
+ min = rex.cap(4).toInt();
+ sec = rex.cap(5).toInt();
+ }
+ positiveOffset = (rex.cap(7) == QStringLiteral("+"));
+ hourOffset = rex.cap(8).toInt();
+ minOffset = rex.cap(9).toInt();
}
+ if (utcOffset)
+ *utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60));
}
}
- buf += getFmtString(frm, dt, dd, ap);
-
- return buf;
+ if (dd)
+ *dd = QDate(year, month, day);
+ if (dt)
+ *dt = QTime(hour, min, sec);
}
#endif // QT_NO_DATESTRING
+
#ifdef Q_OS_WIN
static const int LowerYear = 1980;
#else
@@ -3968,6 +4223,7 @@ static QDate adjustDate(QDate date)
return date;
}
+// Convert passed in UTC datetime into LocalTime and return spec
static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
{
QDate fakeDate = adjustDate(date);
@@ -4021,6 +4277,7 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
}
}
+// Convert passed in LocalTime datetime into UTC
static void localToUtc(QDate &date, QTime &time, int isdst)
{
if (!date.isValid())
@@ -4093,44 +4350,75 @@ static void localToUtc(QDate &date, QTime &time, int isdst)
}
}
+// Convert passed in OffsetFromUTC datetime and offset into UTC
+static void offsetToUtc(QDate *outDate, QTime *outTime, qint32 offset)
+{
+ QDateTimePrivate::addMSecs(*outDate, *outTime, -(qint64(offset) * 1000));
+}
+
+// Convert passed in UTC datetime and offset into OffsetFromUTC
+static void utcToOffset(QDate *outDate, QTime *outTime, qint32 offset)
+{
+ QDateTimePrivate::addMSecs(*outDate, *outTime, (qint64(offset) * 1000));
+}
+
+// Get current date/time in LocalTime and put result in outDate and outTime
QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const
{
outDate = date;
outTime = time;
if (spec == QDateTimePrivate::UTC)
return utcToLocal(outDate, outTime);
+ if (spec == QDateTimePrivate::OffsetFromUTC) {
+ offsetToUtc(&outDate, &outTime, m_offsetFromUtc);
+ return utcToLocal(outDate, outTime);
+ }
return spec;
}
+// Get current date/time in UTC and put result in outDate and outTime
void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
{
outDate = date;
outTime = time;
- const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC;
- if (spec != QDateTimePrivate::UTC && !isOffset)
+ if (spec == QDateTimePrivate::OffsetFromUTC)
+ offsetToUtc(&outDate, &outTime, m_offsetFromUtc);
+ else if (spec != QDateTimePrivate::UTC)
localToUtc(outDate, outTime, (int)spec);
-
- if (isOffset)
- addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000));
}
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
QDebug operator<<(QDebug dbg, const QDate &date)
{
- dbg.nospace() << "QDate(" << date.toString() << ')';
+ dbg.nospace() << "QDate(" << date.toString(QStringLiteral("yyyy-MM-dd")) << ')';
return dbg.space();
}
QDebug operator<<(QDebug dbg, const QTime &time)
{
- dbg.nospace() << "QTime(" << time.toString() << ')';
+ dbg.nospace() << "QTime(" << time.toString(QStringLiteral("HH:mm:ss.zzz")) << ')';
return dbg.space();
}
QDebug operator<<(QDebug dbg, const QDateTime &date)
{
- dbg.nospace() << "QDateTime(" << date.toString() << ')';
+ QString spec;
+ switch (date.d->spec) {
+ case QDateTimePrivate::UTC :
+ spec = QStringLiteral(" Qt::UTC");
+ break;
+ case QDateTimePrivate::OffsetFromUTC :
+ spec = QString::fromUtf8(" Qt::OffsetFromUTC %1s").arg(date.offsetFromUtc());
+ break;
+ case QDateTimePrivate::LocalDST :
+ case QDateTimePrivate::LocalStandard :
+ case QDateTimePrivate::LocalUnknown :
+ default :
+ spec = QStringLiteral(" Qt::LocalTime");
+ }
+ QString output = date.toString(QStringLiteral("yyyy-MM-dd HH:mm:ss.zzz t")) + spec;
+ dbg.nospace() << "QDateTime(" << output << ')';
return dbg.space();
}
#endif
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index 5c1668033c..8b63c5a377 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -203,6 +203,8 @@ public:
QDateTime();
explicit QDateTime(const QDate &);
QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime);
+ // ### Qt 6: Merge with above with default offsetSeconds = 0
+ QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds);
QDateTime(const QDateTime &other);
~QDateTime();
@@ -216,13 +218,21 @@ public:
QDate date() const;
QTime time() const;
Qt::TimeSpec timeSpec() const;
+ int offsetFromUtc() const;
+ QString timeZoneAbbreviation() const;
+
qint64 toMSecsSinceEpoch() const;
+ // ### Qt 6: use quint64 instead of uint
uint toTime_t() const;
+
void setDate(const QDate &date);
void setTime(const QTime &time);
void setTimeSpec(Qt::TimeSpec spec);
+ void setOffsetFromUtc(int offsetSeconds);
void setMSecsSinceEpoch(qint64 msecs);
+ // ### Qt 6: use quint64 instead of uint
void setTime_t(uint secsSince1Jan1970UTC);
+
#ifndef QT_NO_DATESTRING
QString toString(Qt::DateFormat f = Qt::TextDate) const;
QString toString(const QString &format) const;
@@ -232,9 +242,12 @@ public:
QDateTime addYears(int years) const;
QDateTime addSecs(qint64 secs) const;
QDateTime addMSecs(qint64 msecs) const;
+
QDateTime toTimeSpec(Qt::TimeSpec spec) const;
inline QDateTime toLocalTime() const { return toTimeSpec(Qt::LocalTime); }
inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); }
+ QDateTime toOffsetFromUtc(int offsetSeconds) const;
+
qint64 daysTo(const QDateTime &) const;
qint64 secsTo(const QDateTime &) const;
qint64 msecsTo(const QDateTime &) const;
@@ -246,8 +259,10 @@ public:
inline bool operator>(const QDateTime &other) const { return other < *this; }
inline bool operator>=(const QDateTime &other) const { return !(*this < other); }
- void setUtcOffset(int seconds);
- int utcOffset() const;
+#if QT_DEPRECATED_SINCE(5, 2)
+ QT_DEPRECATED void setUtcOffset(int seconds);
+ QT_DEPRECATED int utcOffset() const;
+#endif // QT_DEPRECATED_SINCE
static QDateTime currentDateTime();
static QDateTime currentDateTimeUtc();
@@ -255,8 +270,14 @@ public:
static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
static QDateTime fromString(const QString &s, const QString &format);
#endif
+ // ### Qt 6: use quint64 instead of uint
static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
+ // ### Qt 6: Merge with above with default spec = Qt::LocalTime
+ static QDateTime fromTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec,
+ int offsetFromUtc = 0);
static QDateTime fromMSecsSinceEpoch(qint64 msecs);
+ // ### Qt 6: Merge with above with default spec = Qt::LocalTime
+ static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0);
static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW;
private:
@@ -272,6 +293,10 @@ private:
friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
#endif
+
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
+ friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
+#endif
};
Q_DECLARE_SHARED(QDateTime)
diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h
index c70571d509..f3abcf02d8 100644
--- a/src/corelib/tools/qdatetime_p.h
+++ b/src/corelib/tools/qdatetime_p.h
@@ -81,25 +81,27 @@ class QDateTimePrivate : public QSharedData
public:
enum Spec { LocalUnknown = -1, LocalStandard = 0, LocalDST = 1, UTC = 2, OffsetFromUTC = 3};
- QDateTimePrivate() : spec(LocalUnknown), utcOffset(0) {}
+ QDateTimePrivate() : spec(LocalUnknown), m_offsetFromUtc(0) {}
+ QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec,
+ int offsetSeconds);
QDateTimePrivate(const QDateTimePrivate &other)
- : QSharedData(other), date(other.date), time(other.time), spec(other.spec), utcOffset(other.utcOffset)
+ : QSharedData(other), date(other.date), time(other.time), spec(other.spec),
+ m_offsetFromUtc(other.m_offsetFromUtc)
{}
QDate date;
QTime time;
Spec spec;
- /*!
- \internal
- \since 4.4
-
- The offset in seconds. Applies only when timeSpec() is OffsetFromUTC.
- */
- int utcOffset;
+ int m_offsetFromUtc;
+ // Get current date/time in LocalTime and put result in outDate and outTime
Spec getLocal(QDate &outDate, QTime &outTime) const;
+ // Get current date/time in UTC and put result in outDate and outTime
void getUTC(QDate &outDate, QTime &outTime) const;
+
+ // Add msecs to given datetime and return result
static QDateTime addMSecs(const QDateTime &dt, qint64 msecs);
+ // Add msecs to given datetime and put result in utcDate and utcTime
static void addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs);
static inline qint64 minJd() { return QDate::minJd(); }
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index bc0a14ea72..67e0711796 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -608,14 +608,16 @@ struct BezierEase : public QEasingCurveFunction
sign = -1;
d = d * sign;
- qreal t_i = _fast_cbrt(d);
+ qreal t = _fast_cbrt(d);
//one step of Halley's Method to get a better approximation
- const qreal t_i_cubic = t_i * t_i * t_i;
- qreal t = t_i * (t_i_cubic + d + d) / (t_i_cubic + t_i_cubic + d);
+ const qreal t_cubic = t * t * t;
+ const qreal f = t_cubic + t_cubic + d;
+ if (f != qreal(0.0))
+ t = t * (t_cubic + d + d) / f;
//another step
- /*t_i = t;
+ /*qreal t_i = t;
t_i_cubic = pow(t_i, 3);
t = t_i * (t_i_cubic + d + d) / (t_i_cubic + t_i_cubic + d);*/
diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/tools/qharfbuzz_p.h
index 27ddb44e91..1471fd5712 100644
--- a/src/corelib/tools/qharfbuzz_p.h
+++ b/src/corelib/tools/qharfbuzz_p.h
@@ -140,20 +140,6 @@ typedef enum {
HB_ScriptCount = HB_Script_Inherited
} HB_Script;
-typedef enum {
- HB_NoJustification= 0, /* Justification can't be applied after this glyph */
- HB_Arabic_Space = 1, /* This glyph represents a space inside arabic text */
- HB_Character = 2, /* Inter-character justification point follows this glyph */
- HB_Space = 4, /* This glyph represents a blank outside an Arabic run */
- HB_Arabic_Normal = 7, /* Normal Middle-Of-Word glyph that connects to the right (begin) */
- HB_Arabic_Waw = 8, /* Next character is final form of Waw/Ain/Qaf/Fa */
- HB_Arabic_BaRa = 9, /* Next two chars are Ba + Ra/Ya/AlefMaksura */
- HB_Arabic_Alef = 10, /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */
- HB_Arabic_HaaDal = 11, /* Next character is final form of Haa/Dal/Taa Marbutah */
- HB_Arabic_Seen = 12, /* Initial or Medial form Of Seen/Sad */
- HB_Arabic_Kashida = 13 /* Kashida(U+640) in middle of word */
-} HB_JustificationClass;
-
#ifdef __xlC__
typedef unsigned hb_bitfield;
#else
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index e99a67d1e3..9dd0e6144d 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -509,6 +509,20 @@ private:
static void deleteNode2(QHashData::Node *node);
static void duplicateNode(QHashData::Node *originalNode, void *newNode);
+
+ bool isValidIterator(const iterator &it) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_HASH_NO_ITERATOR_DEBUG)
+ QHashData::Node *node = it.i;
+ while (node->next)
+ node = node->next;
+ return (static_cast<void *>(node) == d);
+#else
+ Q_UNUSED(it);
+ return true;
+#endif
+ }
+ friend class QSet<Key>;
};
@@ -831,9 +845,27 @@ Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey)
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(iterator it)
{
+ Q_ASSERT_X(isValidIterator(it), "QHash::erase", "The specified iterator argument 'it' is invalid");
+
if (it == iterator(e))
return it;
+ if (d->ref.isShared()) {
+ int bucketNum = (it.i->h % d->numBuckets);
+ iterator bucketIterator(*(d->buckets + bucketNum));
+ int stepsFromBucketStartToIte = 0;
+ while (bucketIterator != it) {
+ ++stepsFromBucketStartToIte;
+ ++bucketIterator;
+ }
+ detach();
+ it = iterator(*(d->buckets + bucketNum));
+ while (stepsFromBucketStartToIte > 0) {
+ --stepsFromBucketStartToIte;
+ ++it;
+ }
+ }
+
iterator ret = it;
++ret;
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index b9ca1b964a..28386c632c 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -48,6 +48,8 @@
#include <iterator>
#include <list>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
@@ -91,7 +93,7 @@ public:
inline int size() const { return d->size; }
inline void detach()
- { if (d->ref.isShared()) detach_helper(); }
+ { if (d->ref.isShared()) detach_helper2(this->e); }
inline bool isDetached() const { return !d->ref.isShared(); }
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; }
inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; }
@@ -232,6 +234,7 @@ public:
private:
void detach_helper();
+ iterator detach_helper2(iterator);
void freeData(QLinkedListData*);
};
@@ -245,6 +248,14 @@ inline QLinkedList<T>::~QLinkedList()
template <typename T>
void QLinkedList<T>::detach_helper()
{
+ detach_helper2(this->e);
+}
+
+template <typename T>
+typename QLinkedList<T>::iterator QLinkedList<T>::detach_helper2(iterator orgite)
+{
+ // detach and convert orgite to an iterator in the detached instance
+ bool isEndIterator = (orgite.i == this->e);
union { QLinkedListData *d; Node *e; } x;
x.d = new QLinkedListData;
x.d->ref.initializeOwned();
@@ -252,6 +263,22 @@ void QLinkedList<T>::detach_helper()
x.d->sharable = true;
Node *original = e->n;
Node *copy = x.e;
+ Node *org = orgite.i;
+
+ while (original != org) {
+ QT_TRY {
+ copy->n = new Node(original->t);
+ copy->n->p = copy;
+ original = original->n;
+ copy = copy->n;
+ } QT_CATCH(...) {
+ copy->n = x.e;
+ Q_ASSERT(!x.d->ref.deref()); // Don't trigger assert in free
+ freeData(x.d);
+ QT_RETHROW;
+ }
+ }
+ iterator r(copy);
while (original != e) {
QT_TRY {
copy->n = new Node(original->t);
@@ -270,6 +297,9 @@ void QLinkedList<T>::detach_helper()
if (!d->ref.deref())
freeData(d);
d = x.d;
+ if (!isEndIterator)
+ ++r; // since we stored the element right before the original node.
+ return r;
}
template <typename T>
@@ -376,7 +406,7 @@ template <typename T>
bool QLinkedList<T>::removeOne(const T &_t)
{
detach();
- iterator it = qFind(begin(), end(), _t);
+ iterator it = std::find(begin(), end(), _t);
if (it != end()) {
erase(it);
return true;
@@ -425,6 +455,9 @@ int QLinkedList<T>::count(const T &t) const
template <typename T>
typename QLinkedList<T>::iterator QLinkedList<T>::insert(iterator before, const T &t)
{
+ if (d->ref.isShared())
+ before = detach_helper2(before);
+
Node *i = before.i;
Node *m = new Node(t);
m->n = i;
@@ -448,7 +481,9 @@ typename QLinkedList<T>::iterator QLinkedList<T>::erase(typename QLinkedList<T>:
template <typename T>
typename QLinkedList<T>::iterator QLinkedList<T>::erase(iterator pos)
{
- detach();
+ if (d->ref.isShared())
+ pos = detach_helper2(pos);
+
Node *i = pos.i;
if (i != e) {
Node *n = i;
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 72e1403e76..c81968dce1 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -346,6 +346,11 @@ private:
void node_destruct(Node *n);
void node_copy(Node *from, Node *to, Node *src);
void node_destruct(Node *from, Node *to);
+
+ bool isValidIterator(const iterator &i) const
+ {
+ return (constBegin().i <= i.i) && (i.i <= constEnd().i);
+ }
};
#if defined(Q_CC_BOR)
@@ -433,8 +438,14 @@ Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
template <typename T>
inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QList::insert", "The specified iterator argument 'before' is invalid");
+
int iBefore = int(before.i - reinterpret_cast<Node *>(p.begin()));
- Node *n = reinterpret_cast<Node *>(p.insert(iBefore));
+ Node *n = 0;
+ if (d->ref.isShared())
+ n = detach_helper_grow(iBefore, 1);
+ else
+ n = reinterpret_cast<Node *>(p.insert(iBefore));
QT_TRY {
node_construct(n, t);
} QT_CATCH(...) {
@@ -445,8 +456,16 @@ inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
}
template <typename T>
inline typename QList<T>::iterator QList<T>::erase(iterator it)
-{ node_destruct(it.i);
- return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i))); }
+{
+ Q_ASSERT_X(isValidIterator(it), "QList::erase", "The specified iterator argument 'it' is invalid");
+ if (d->ref.isShared()) {
+ int offset = int(it.i - reinterpret_cast<Node *>(p.begin()));
+ it = begin(); // implies detach()
+ it += offset;
+ }
+ node_destruct(it.i);
+ return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i)));
+}
template <typename T>
inline const T &QList<T>::at(int i) const
{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::at", "index out of range");
@@ -807,6 +826,19 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList<T>::iterator afirst,
typename QList<T>::iterator alast)
{
+ Q_ASSERT_X(isValidIterator(afirst), "QList::erase", "The specified iterator argument 'afirst' is invalid");
+ Q_ASSERT_X(isValidIterator(alast), "QList::erase", "The specified iterator argument 'alast' is invalid");
+
+ if (d->ref.isShared()) {
+ // ### A block is erased and a detach is needed. We should shrink and only copy relevant items.
+ int offsetfirst = int(afirst.i - reinterpret_cast<Node *>(p.begin()));
+ int offsetlast = int(alast.i - reinterpret_cast<Node *>(p.begin()));
+ afirst = begin(); // implies detach()
+ alast = afirst;
+ afirst += offsetfirst;
+ alast += offsetlast;
+ }
+
for (Node *n = afirst.i; n < alast.i; ++n)
node_destruct(n);
int idx = afirst - begin();
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index ede783bf9e..060b220a4a 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -652,6 +652,11 @@ const QLocaleData *QLocaleData::c()
return c_data;
}
+static inline QString getLocaleData(const ushort *data, int size)
+{
+ return size > 0 ? QString::fromRawData(reinterpret_cast<const QChar *>(data), size) : QString();
+}
+
static QString getLocaleListData(const ushort *data, int size, int index)
{
static const ushort separator = ';';
@@ -665,14 +670,7 @@ static QString getLocaleListData(const ushort *data, int size, int index)
const ushort *end = data;
while (size > 0 && *end != separator)
++end, --size;
- if (end-data == 0)
- return QString();
- return QString::fromRawData(reinterpret_cast<const QChar*>(data), end-data);
-}
-
-static inline QString getLocaleData(const ushort *data, int size)
-{
- return size ? QString::fromRawData(reinterpret_cast<const QChar*>(data), size) : QString();
+ return getLocaleData(data, end - data);
}
@@ -1576,7 +1574,7 @@ QString QLocale::toString(qulonglong i) const
QString QLocale::toString(const QDate &date, const QString &format) const
{
- return d->dateTimeToString(format, &date, 0, this);
+ return d->dateTimeToString(format, QDateTime(), date, QTime(), this);
}
/*!
@@ -1620,33 +1618,6 @@ static bool timeFormatContainsAP(const QString &format)
return false;
}
-static QString timeZone()
-{
-#if defined(Q_OS_WINCE)
- TIME_ZONE_INFORMATION info;
- DWORD res = GetTimeZoneInformation(&info);
- if (res == TIME_ZONE_ID_UNKNOWN)
- return QString();
- return QString::fromWCharArray(info.StandardName);
-#elif defined(Q_OS_WIN)
- _tzset();
-# if defined(_MSC_VER) && _MSC_VER >= 1400
- size_t returnSize = 0;
- char timeZoneName[512];
- if (_get_tzname(&returnSize, timeZoneName, 512, 1))
- return QString();
- return QString::fromLocal8Bit(timeZoneName);
-# else
- return QString::fromLocal8Bit(_tzname[1]);
-# endif
-#elif defined(Q_OS_VXWORKS)
- return QString();
-#else
- tzset();
- return QString::fromLocal8Bit(tzname[1]);
-#endif
-}
-
/*!
Returns a localized string representation of the given \a time according
to the specified \a format.
@@ -1654,7 +1625,7 @@ static QString timeZone()
*/
QString QLocale::toString(const QTime &time, const QString &format) const
{
- return d->dateTimeToString(format, 0, &time, this);
+ return d->dateTimeToString(format, QDateTime(), QDate(), time, this);
}
/*!
@@ -1667,9 +1638,7 @@ QString QLocale::toString(const QTime &time, const QString &format) const
QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
{
- const QDate dt = dateTime.date();
- const QTime tm = dateTime.time();
- return d->dateTimeToString(format, &dt, &tm, this);
+ return d->dateTimeToString(format, dateTime, QDate(), QTime(), this);
}
/*!
@@ -2555,28 +2524,27 @@ QString QLocale::pmText() const
}
-QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *date, const QTime *time,
+QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime &datetime,
+ const QDate &dateOnly, const QTime &timeOnly,
const QLocale *q) const
{
- Q_ASSERT(date || time);
- if ((date && !date->isValid()) || (time && !time->isValid()))
+ QDate date;
+ QTime time;
+ bool formatDate = false;
+ bool formatTime = false;
+ if (datetime.isValid()) {
+ date = datetime.date();
+ time = datetime.time();
+ formatDate = true;
+ formatTime = true;
+ } else if (dateOnly.isValid()) {
+ date = dateOnly;
+ formatDate = true;
+ } else if (timeOnly.isValid()) {
+ time = timeOnly;
+ formatTime = true;
+ } else {
return QString();
- const bool format_am_pm = time && timeFormatContainsAP(format);
-
- enum { AM, PM } am_pm = AM;
- int hour12 = time ? time->hour() : -1;
- if (time) {
- if (hour12 == 0) {
- am_pm = AM;
- hour12 = 12;
- } else if (hour12 < 12) {
- am_pm = AM;
- } else if (hour12 == 12) {
- am_pm = PM;
- } else {
- am_pm = PM;
- hour12 -= 12;
- }
}
QString result;
@@ -2591,7 +2559,7 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
const QChar c = format.at(i);
int repeat = qt_repeatCount(format, i);
bool used = false;
- if (date) {
+ if (formatDate) {
switch (c.unicode()) {
case 'y':
used = true;
@@ -2601,11 +2569,14 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = 2;
switch (repeat) {
- case 4:
- result.append(longLongToString(date->year(), -1, 10, 4, QLocalePrivate::ZeroPadded));
+ case 4: {
+ const int yr = date.year();
+ const int len = (yr < 0) ? 5 : 4;
+ result.append(longLongToString(yr, -1, 10, len, QLocalePrivate::ZeroPadded));
break;
+ }
case 2:
- result.append(longLongToString(date->year() % 100, -1, 10, 2,
+ result.append(longLongToString(date.year() % 100, -1, 10, 2,
QLocalePrivate::ZeroPadded));
break;
default:
@@ -2620,16 +2591,16 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 4);
switch (repeat) {
case 1:
- result.append(longLongToString(date->month()));
+ result.append(longLongToString(date.month()));
break;
case 2:
- result.append(longLongToString(date->month(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(date.month(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
case 3:
- result.append(q->monthName(date->month(), QLocale::ShortFormat));
+ result.append(q->monthName(date.month(), QLocale::ShortFormat));
break;
case 4:
- result.append(q->monthName(date->month(), QLocale::LongFormat));
+ result.append(q->monthName(date.month(), QLocale::LongFormat));
break;
}
break;
@@ -2639,16 +2610,16 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 4);
switch (repeat) {
case 1:
- result.append(longLongToString(date->day()));
+ result.append(longLongToString(date.day()));
break;
case 2:
- result.append(longLongToString(date->day(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(date.day(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
case 3:
- result.append(q->dayName(date->dayOfWeek(), QLocale::ShortFormat));
+ result.append(q->dayName(date.dayOfWeek(), QLocale::ShortFormat));
break;
case 4:
- result.append(q->dayName(date->dayOfWeek(), QLocale::LongFormat));
+ result.append(q->dayName(date.dayOfWeek(), QLocale::LongFormat));
break;
}
break;
@@ -2657,12 +2628,18 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
break;
}
}
- if (!used && time) {
+ if (!used && formatTime) {
switch (c.unicode()) {
case 'h': {
used = true;
repeat = qMin(repeat, 2);
- const int hour = format_am_pm ? hour12 : time->hour();
+ int hour = time.hour();
+ if (timeFormatContainsAP(format)) {
+ if (hour > 12)
+ hour -= 12;
+ else if (hour == 0)
+ hour = 12;
+ }
switch (repeat) {
case 1:
@@ -2679,10 +2656,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time->hour()));
+ result.append(longLongToString(time.hour()));
break;
case 2:
- result.append(longLongToString(time->hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2692,10 +2669,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time->minute()));
+ result.append(longLongToString(time.minute()));
break;
case 2:
- result.append(longLongToString(time->minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2705,10 +2682,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time->second()));
+ result.append(longLongToString(time.second()));
break;
case 2:
- result.append(longLongToString(time->second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2720,7 +2697,7 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
} else {
repeat = 1;
}
- result.append(am_pm == AM ? q->amText().toLower() : q->pmText().toLower());
+ result.append(time.hour() < 12 ? q->amText().toLower() : q->pmText().toLower());
break;
case 'A':
@@ -2730,7 +2707,7 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
} else {
repeat = 1;
}
- result.append(am_pm == AM ? q->amText().toUpper() : q->pmText().toUpper());
+ result.append(time.hour() < 12 ? q->amText().toUpper() : q->pmText().toUpper());
break;
case 'z':
@@ -2742,10 +2719,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
}
switch (repeat) {
case 1:
- result.append(longLongToString(time->msec()));
+ result.append(longLongToString(time.msec()));
break;
case 3:
- result.append(longLongToString(time->msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2753,8 +2730,14 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
case 't':
used = true;
repeat = 1;
- result.append(timeZone());
+ // If we have a QDateTime use the time spec otherwise use the current system tzname
+ if (formatDate) {
+ result.append(datetime.timeZoneAbbreviation());
+ } else {
+ result.append(QDateTime::currentDateTime().timeZoneAbbreviation());
+ }
break;
+
default:
break;
}
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 78fa336b7c..0fc3f87726 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -775,13 +775,14 @@ public:
SouthSudan = 254,
Bonaire = 255,
SintMaarten = 256,
+ Kosovo = 257,
DemocraticRepublicOfCongo = CongoKinshasa,
PeoplesRepublicOfCongo = CongoBrazzaville,
DemocraticRepublicOfKorea = NorthKorea,
RepublicOfKorea = SouthKorea,
RussianFederation = Russia,
SyrianArabRepublic = Syria,
- LastCountry = SintMaarten
+ LastCountry = Kosovo
};
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index 150e4a18ce..a3b38c41f4 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -92,7 +92,7 @@
\note For the current keyboard input locale take a look at
QInputMethod::locale().
- QLocale's data is based on Common Locale Data Repository v23.
+ QLocale's data is based on Common Locale Data Repository v23.1.
The double-to-string and string-to-double conversion functions are
covered by the following licenses:
@@ -584,6 +584,7 @@
\value SouthKorea
\value DemocraticRepublicOfKorea Obsolete, please use NorthKorea
\value RepublicOfKorea Obsolete, please use SouthKorea
+ \value Kosovo
\value Kuwait
\value Kyrgyzstan
\value Laos
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
index 6642f824ea..46b3eef658 100644
--- a/src/corelib/tools/qlocale_data_p.h
+++ b/src/corelib/tools/qlocale_data_p.h
@@ -77,8 +77,8 @@ static const int ImperialMeasurementSystemsCount =
// GENERATED PART STARTS HERE
/*
- This part of the file was generated on 2013-03-16 from the
- Common Locale Data Repository v23
+ This part of the file was generated on 2013-08-10 from the
+ Common Locale Data Repository v23.1
http://www.unicode.org/cldr/
@@ -771,215 +771,215 @@ static const quint16 locale_index[] = {
3, // Afar
6, // Afrikaans
8, // Albanian
- 10, // Amharic
- 11, // Arabic
- 37, // Armenian
- 38, // Assamese
+ 11, // Amharic
+ 12, // Arabic
+ 38, // Armenian
+ 39, // Assamese
0, // Aymara
- 39, // Azerbaijani
+ 40, // Azerbaijani
0, // Bashkir
- 41, // Basque
- 42, // Bengali
- 44, // Dzongkha
+ 42, // Basque
+ 43, // Bengali
+ 45, // Dzongkha
0, // Bihari
0, // Bislama
- 45, // Breton
- 46, // Bulgarian
- 47, // Burmese
- 48, // Belarusian
- 49, // Khmer
- 50, // Catalan
- 52, // Chinese
+ 46, // Breton
+ 47, // Bulgarian
+ 48, // Burmese
+ 49, // Belarusian
+ 50, // Khmer
+ 51, // Catalan
+ 53, // Chinese
0, // Corsican
- 59, // Croatian
- 61, // Czech
- 62, // Danish
- 63, // Dutch
- 69, // English
+ 60, // Croatian
+ 62, // Czech
+ 63, // Danish
+ 64, // Dutch
+ 70, // English
0, // Esperanto
- 140, // Estonian
- 141, // Faroese
+ 141, // Estonian
+ 142, // Faroese
0, // Fijian
- 142, // Finnish
- 143, // French
+ 143, // Finnish
+ 144, // French
0, // Western Frisian
- 187, // Gaelic
- 188, // Galician
- 189, // Georgian
- 190, // German
- 196, // Greek
- 198, // Greenlandic
+ 188, // Gaelic
+ 189, // Galician
+ 190, // Georgian
+ 191, // German
+ 197, // Greek
+ 199, // Greenlandic
0, // Guarani
- 199, // Gujarati
- 200, // Hausa
- 203, // Hebrew
- 204, // Hindi
- 205, // Hungarian
- 206, // Icelandic
- 207, // Indonesian
- 208, // Interlingua
+ 200, // Gujarati
+ 201, // Hausa
+ 204, // Hebrew
+ 205, // Hindi
+ 206, // Hungarian
+ 207, // Icelandic
+ 208, // Indonesian
+ 209, // Interlingua
0, // Interlingue
0, // Inuktitut
0, // Inupiak
- 209, // Irish
- 210, // Italian
- 213, // Japanese
+ 210, // Irish
+ 211, // Italian
+ 214, // Japanese
0, // Javanese
- 214, // Kannada
- 215, // Kashmiri
- 216, // Kazakh
- 217, // Kinyarwanda
- 218, // Kirghiz
- 219, // Korean
+ 215, // Kannada
+ 216, // Kashmiri
+ 217, // Kazakh
+ 218, // Kinyarwanda
+ 219, // Kirghiz
+ 220, // Korean
0, // Kurdish
- 221, // Rundi
- 222, // Lao
+ 222, // Rundi
+ 223, // Lao
0, // Latin
- 223, // Latvian
- 224, // Lingala
- 228, // Lithuanian
- 229, // Macedonian
- 230, // Malagasy
- 231, // Malay
- 234, // Malayalam
- 235, // Maltese
+ 224, // Latvian
+ 225, // Lingala
+ 229, // Lithuanian
+ 230, // Macedonian
+ 231, // Malagasy
+ 232, // Malay
+ 235, // Malayalam
+ 236, // Maltese
0, // Maori
- 236, // Marathi
+ 237, // Marathi
0, // Marshallese
- 237, // Mongolian
+ 238, // Mongolian
0, // Nauru
- 238, // Nepali
- 240, // NorwegianBokmal
+ 239, // Nepali
+ 241, // NorwegianBokmal
0, // Occitan
- 241, // Oriya
- 242, // Pashto
- 243, // Persian
- 245, // Polish
- 246, // Portuguese
- 255, // Punjabi
+ 242, // Oriya
+ 243, // Pashto
+ 244, // Persian
+ 246, // Polish
+ 247, // Portuguese
+ 256, // Punjabi
0, // Quechua
- 257, // Romansh
- 258, // Romanian
- 260, // Russian
+ 258, // Romansh
+ 259, // Romanian
+ 261, // Russian
0, // Samoan
- 266, // Sango
+ 267, // Sango
0, // Sanskrit
- 267, // Serbian
- 273, // Ossetic
- 275, // Southern Sotho
- 277, // Tswana
- 279, // Shona
+ 268, // Serbian
+ 276, // Ossetic
+ 278, // Southern Sotho
+ 280, // Tswana
+ 282, // Shona
0, // Sindhi
- 280, // Sinhala
- 281, // Swati
- 283, // Slovak
- 284, // Slovenian
- 285, // Somali
- 289, // Spanish
+ 283, // Sinhala
+ 284, // Swati
+ 286, // Slovak
+ 287, // Slovenian
+ 288, // Somali
+ 292, // Spanish
0, // Sundanese
- 315, // Swahili
- 318, // Swedish
+ 318, // Swahili
+ 321, // Swedish
0, // Sardinian
- 321, // Tajik
- 322, // Tamil
+ 324, // Tajik
+ 325, // Tamil
0, // Tatar
- 326, // Telugu
- 327, // Thai
- 328, // Tibetan
- 330, // Tigrinya
- 332, // Tongan
- 333, // Tsonga
- 334, // Turkish
+ 329, // Telugu
+ 330, // Thai
+ 331, // Tibetan
+ 333, // Tigrinya
+ 335, // Tongan
+ 336, // Tsonga
+ 337, // Turkish
0, // Turkmen
0, // Tahitian
0, // Uighur
- 336, // Ukrainian
- 337, // Urdu
- 339, // Uzbek
- 342, // Vietnamese
+ 339, // Ukrainian
+ 340, // Urdu
+ 342, // Uzbek
+ 345, // Vietnamese
0, // Volapuk
- 343, // Welsh
+ 346, // Welsh
0, // Wolof
- 344, // Xhosa
+ 347, // Xhosa
0, // Yiddish
- 345, // Yoruba
+ 348, // Yoruba
0, // Zhuang
- 346, // Zulu
- 347, // NorwegianNynorsk
- 348, // Bosnian
+ 349, // Zulu
+ 350, // NorwegianNynorsk
+ 351, // Bosnian
0, // Divehi
- 350, // Manx
- 351, // Cornish
- 352, // Akan
- 353, // Konkani
+ 353, // Manx
+ 354, // Cornish
+ 355, // Akan
+ 356, // Konkani
0, // Ga
- 354, // Igbo
- 355, // Kamba
+ 357, // Igbo
+ 358, // Kamba
0, // Syriac
- 356, // Blin
+ 359, // Blin
0, // Geez
0, // Koro
0, // Sidamo
0, // Atsam
- 357, // Tigre
+ 360, // Tigre
0, // Jju
- 358, // Friulian
- 359, // Venda
- 360, // Ewe
- 362, // Walamo
- 363, // Hawaiian
+ 361, // Friulian
+ 362, // Venda
+ 363, // Ewe
+ 365, // Walamo
+ 366, // Hawaiian
0, // Tyap
0, // Nyanja
- 364, // Filipino
- 365, // Swiss German
- 366, // Sichuan Yi
+ 367, // Filipino
+ 368, // Swiss German
+ 369, // Sichuan Yi
0, // Kpelle
0, // Low German
- 367, // South Ndebele
- 368, // Northern Sotho
- 369, // Northern Sami
+ 370, // South Ndebele
+ 371, // Northern Sotho
+ 372, // Northern Sami
0, // Taroko
- 371, // Gusii
- 372, // Taita
- 373, // Fulah
- 374, // Kikuyu
- 375, // Samburu
- 376, // Sena
- 377, // North Ndebele
- 378, // Rombo
- 379, // Tachelhit
- 381, // Kabyle
- 382, // Nyankole
- 383, // Bena
- 384, // Vunjo
- 385, // Bambara
- 386, // Embu
- 387, // Cherokee
- 388, // Morisyen
- 389, // Makonde
- 390, // Langi
- 391, // Ganda
- 392, // Bemba
- 393, // Kabuverdianu
- 394, // Meru
- 395, // Kalenjin
- 396, // Nama
- 397, // Machame
- 398, // Colognian
- 399, // Masai
- 401, // Soga
- 402, // Luyia
- 403, // Asu
- 404, // Teso
- 406, // Saho
- 407, // Koyra Chiini
- 408, // Rwa
- 409, // Luo
- 410, // Chiga
- 411, // Central Morocco Tamazight
- 412, // Koyraboro Senni
- 413, // Shambala
- 414, // Bodo
+ 374, // Gusii
+ 375, // Taita
+ 376, // Fulah
+ 377, // Kikuyu
+ 378, // Samburu
+ 379, // Sena
+ 380, // North Ndebele
+ 381, // Rombo
+ 382, // Tachelhit
+ 384, // Kabyle
+ 385, // Nyankole
+ 386, // Bena
+ 387, // Vunjo
+ 388, // Bambara
+ 389, // Embu
+ 390, // Cherokee
+ 391, // Morisyen
+ 392, // Makonde
+ 393, // Langi
+ 394, // Ganda
+ 395, // Bemba
+ 396, // Kabuverdianu
+ 397, // Meru
+ 398, // Kalenjin
+ 399, // Nama
+ 400, // Machame
+ 401, // Colognian
+ 402, // Masai
+ 404, // Soga
+ 405, // Luyia
+ 406, // Asu
+ 407, // Teso
+ 409, // Saho
+ 410, // Koyra Chiini
+ 411, // Rwa
+ 412, // Luo
+ 413, // Chiga
+ 414, // Central Morocco Tamazight
+ 415, // Koyraboro Senni
+ 416, // Shambala
+ 417, // Bodo
0, // Avaric
0, // Chamorro
0, // Chechen
@@ -994,37 +994,37 @@ static const quint16 locale_index[] = {
0, // Kongo
0, // Kwanyama
0, // Limburgish
- 415, // LubaKatanga
+ 418, // LubaKatanga
0, // Luxembourgish
0, // Navaho
0, // Ndonga
0, // Ojibwa
0, // Pali
0, // Walloon
- 416, // Aghem
- 417, // Basaa
- 418, // Zarma
- 419, // Duala
- 420, // JolaFonyi
- 421, // Ewondo
- 422, // Bafia
- 423, // MakhuwaMeetto
- 424, // Mundang
- 425, // Kwasio
- 426, // Nuer
- 427, // Sakha
- 428, // Sangu
- 429, // Congo Swahili
- 430, // Tasawaq
- 431, // Vai
- 433, // Walser
- 434, // Yangben
+ 419, // Aghem
+ 420, // Basaa
+ 421, // Zarma
+ 422, // Duala
+ 423, // JolaFonyi
+ 424, // Ewondo
+ 425, // Bafia
+ 426, // MakhuwaMeetto
+ 427, // Mundang
+ 428, // Kwasio
+ 429, // Nuer
+ 430, // Sakha
+ 431, // Sangu
+ 432, // Congo Swahili
+ 433, // Tasawaq
+ 434, // Vai
+ 436, // Walser
+ 437, // Yangben
0, // Avestan
- 435, // Asturian
- 436, // Ngomba
- 437, // Kako
- 438, // Meta
- 439, // Ngiemboon
+ 438, // Asturian
+ 439, // Ngomba
+ 440, // Kako
+ 441, // Meta
+ 442, // Ngiemboon
0, // Aragonese
0, // Akkadian
0, // AncientEgyptian
@@ -1091,436 +1091,439 @@ static const QLocaleData locale_data[] = {
{ 5, 7, 148, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 72,10 , 99,16 , 37,5 , 8,10 , 653,48 , 701,92 , 134,24 , 653,48 , 701,92 , 134,24 , 290,21 , 311,58 , 369,14 , 290,21 , 311,58 , 369,14 , 4,3 , 4,3 , {78,65,68}, 12,1 , 58,23 , 14,5 , 4,0 , 50,9 , 70,7 , 2, 1, 1, 6, 7 }, // Afrikaans/Latin/Namibia
{ 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {65,76,76}, 13,3 , 0,7 , 4,4 , 4,0 , 77,5 , 82,9 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania
{ 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {77,75,68}, 16,3 , 0,7 , 4,4 , 4,0 , 77,5 , 91,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia
- { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 14,6 , 14,6 , 20,9 , 29,8 , 141,10 , 10,17 , 18,7 , 25,12 , 943,46 , 989,61 , 1050,24 , 1074,46 , 1120,62 , 1050,24 , 483,27 , 510,28 , 538,14 , 483,27 , 510,28 , 538,14 , 9,3 , 9,4 , {69,84,66}, 19,2 , 81,34 , 4,4 , 8,6 , 99,4 , 103,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
- { 8, 1, 64, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,71,80}, 21,5 , 115,70 , 14,5 , 19,6 , 108,7 , 115,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
- { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,90,68}, 26,5 , 185,91 , 14,5 , 19,6 , 108,7 , 118,7 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/Algeria
- { 8, 1, 17, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {66,72,68}, 31,5 , 276,91 , 14,5 , 19,6 , 108,7 , 125,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
- { 8, 1, 42, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {88,65,70}, 36,4 , 367,84 , 14,5 , 19,6 , 108,7 , 132,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
- { 8, 1, 48, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,77,70}, 40,7 , 451,105 , 14,5 , 19,6 , 108,7 , 136,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
- { 8, 1, 59, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,74,70}, 5,3 , 556,84 , 14,5 , 19,6 , 108,7 , 145,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
- { 8, 1, 67, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,82,78}, 8,3 , 640,91 , 14,5 , 19,6 , 108,7 , 151,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
- { 8, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1492,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,81,68}, 47,5 , 731,84 , 14,5 , 19,6 , 108,7 , 158,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
- { 8, 1, 105, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 52,1 , 815,133 , 14,5 , 19,6 , 108,7 , 164,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
- { 8, 1, 109, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {74,79,68}, 53,5 , 948,84 , 14,5 , 19,6 , 108,7 , 171,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
- { 8, 1, 115, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,87,68}, 58,5 , 1032,84 , 14,5 , 19,6 , 108,7 , 177,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
- { 8, 1, 119, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,66,80}, 63,5 , 1116,84 , 14,5 , 19,6 , 108,7 , 183,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
- { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,89,68}, 68,5 , 1200,77 , 14,5 , 19,6 , 108,7 , 188,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
- { 8, 1, 136, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,82,79}, 73,5 , 1277,112 , 14,5 , 19,6 , 108,7 , 193,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Mauritania
- { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1584,71 , 1655,71 , 1726,24 , 1655,71 , 1750,71 , 1821,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 78,5 , 1389,77 , 14,5 , 19,6 , 108,7 , 202,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
- { 8, 1, 162, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {79,77,82}, 83,5 , 1466,77 , 14,5 , 19,6 , 108,7 , 208,5 , 3, 0, 6, 4, 5 }, // Arabic/Arabic/Oman
- { 8, 1, 165, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 52,1 , 815,133 , 14,5 , 19,6 , 108,7 , 213,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/PalestinianTerritories
- { 8, 1, 175, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {81,65,82}, 88,5 , 1543,70 , 4,4 , 4,0 , 108,7 , 219,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
- { 8, 1, 186, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,65,82}, 93,5 , 1613,77 , 4,4 , 4,0 , 108,7 , 222,24 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/SaudiArabia
- { 8, 1, 194, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,79,83}, 98,1 , 1690,77 , 14,5 , 19,6 , 108,7 , 246,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
- { 8, 1, 201, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,68,71}, 0,0 , 1767,84 , 14,5 , 19,6 , 108,7 , 253,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
- { 8, 1, 207, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,89,80}, 99,5 , 1851,77 , 4,4 , 4,0 , 108,7 , 260,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
- { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {84,78,68}, 104,5 , 1928,77 , 4,4 , 4,0 , 108,7 , 265,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
- { 8, 1, 223, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {65,69,68}, 109,5 , 2005,91 , 14,5 , 19,6 , 108,7 , 269,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/UnitedArabEmirates
- { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 78,5 , 1389,77 , 14,5 , 19,6 , 108,7 , 293,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/WesternSahara
- { 8, 1, 237, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {89,69,82}, 114,5 , 2096,70 , 4,4 , 4,0 , 108,7 , 308,5 , 0, 0, 6, 4, 5 }, // Arabic/Arabic/Yemen
- { 9, 10, 11, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 58,7 , 58,7 , 187,8 , 195,21 , 61,4 , 65,10 , 1845,48 , 1893,106 , 1999,24 , 1845,48 , 1893,106 , 1999,24 , 618,28 , 646,62 , 708,15 , 618,28 , 646,62 , 708,15 , 13,12 , 14,12 , {65,77,68}, 119,3 , 2166,46 , 25,5 , 4,0 , 313,7 , 320,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
- { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 216,8 , 224,18 , 75,8 , 83,12 , 2023,62 , 2085,88 , 158,27 , 2023,62 , 2085,88 , 158,27 , 723,37 , 760,58 , 85,14 , 723,37 , 760,58 , 85,14 , 25,9 , 26,7 , {73,78,82}, 122,1 , 0,7 , 14,5 , 4,0 , 328,7 , 335,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
- { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2173,48 , 2221,77 , 158,27 , 2173,48 , 2221,77 , 158,27 , 818,26 , 844,67 , 99,14 , 818,26 , 844,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 123,4 , 2212,41 , 14,5 , 4,0 , 339,12 , 351,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
- { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2298,77 , 2298,77 , 158,27 , 2298,77 , 2298,77 , 158,27 , 911,67 , 911,67 , 99,14 , 911,67 , 911,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 127,4 , 2253,12 , 14,5 , 4,0 , 361,10 , 361,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
- { 14, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 65,9 , 65,9 , 72,10 , 269,18 , 37,5 , 8,10 , 2375,48 , 2423,93 , 2516,24 , 2375,48 , 2423,93 , 2516,24 , 978,21 , 999,68 , 1067,14 , 978,21 , 999,68 , 1081,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2265,12 , 25,5 , 30,7 , 371,7 , 378,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
- { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {66,68,84}, 132,1 , 2277,21 , 0,4 , 37,6 , 386,5 , 391,8 , 2, 1, 5, 6, 7 }, // Bengali/Bengali/Bangladesh
- { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {73,78,82}, 122,1 , 2298,19 , 0,4 , 37,6 , 386,5 , 399,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
- { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 93,9 , 93,9 , 93,9 , 93,9 , 72,10 , 293,30 , 95,22 , 117,27 , 2663,63 , 2726,191 , 2917,27 , 2944,27 , 2971,132 , 3103,27 , 1208,34 , 1242,79 , 1321,27 , 1208,34 , 1242,79 , 1321,27 , 43,5 , 40,6 , {66,84,78}, 133,3 , 2317,15 , 4,4 , 4,0 , 403,6 , 409,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
- { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 3130,55 , 3185,78 , 158,27 , 3130,55 , 3185,78 , 158,27 , 1348,33 , 1381,43 , 1424,21 , 1348,33 , 1381,43 , 1424,21 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2332,11 , 14,5 , 4,0 , 414,9 , 423,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
- { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 340,18 , 37,5 , 8,10 , 3263,59 , 3322,82 , 3404,24 , 3263,59 , 3322,82 , 3404,24 , 1445,21 , 1466,55 , 1521,14 , 1445,21 , 1466,55 , 1521,14 , 48,7 , 46,7 , {66,71,78}, 136,3 , 2343,47 , 25,5 , 4,0 , 428,9 , 437,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
- { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 3428,43 , 3471,88 , 3559,24 , 3428,43 , 3471,88 , 3559,24 , 1535,25 , 1560,54 , 1614,14 , 1535,25 , 1560,54 , 1614,14 , 55,5 , 53,3 , {77,77,75}, 139,1 , 2390,18 , 14,5 , 4,0 , 445,3 , 448,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
- { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 358,6 , 10,17 , 144,5 , 149,10 , 3583,48 , 3631,99 , 3730,24 , 3754,48 , 3802,95 , 3897,24 , 1628,21 , 1649,56 , 1705,14 , 1628,21 , 1649,56 , 1705,14 , 60,10 , 56,13 , {66,89,82}, 140,2 , 2408,23 , 4,4 , 4,0 , 454,10 , 464,8 , 0, 0, 7, 6, 7 }, // Belarusian/Cyrillic/Belarus
- { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 109,9 , 364,8 , 10,17 , 18,7 , 25,12 , 3921,71 , 3921,71 , 158,27 , 3921,71 , 3921,71 , 158,27 , 1719,46 , 1719,46 , 1765,14 , 1719,46 , 1719,46 , 1765,14 , 70,5 , 69,5 , {75,72,82}, 142,1 , 2431,18 , 4,4 , 8,6 , 472,5 , 477,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
- { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 4,4 , 8,6 , 484,6 , 490,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
- { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 4,4 , 8,6 , 484,6 , 497,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
- { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 393,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {67,78,89}, 143,1 , 2469,10 , 4,4 , 8,6 , 504,4 , 508,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
- { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2479,9 , 4,4 , 4,0 , 504,4 , 510,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/HongKong
- { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2488,10 , 4,4 , 4,0 , 504,4 , 519,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
- { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 27,8 , 399,13 , 188,7 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {83,71,68}, 12,1 , 2498,11 , 4,4 , 4,0 , 504,4 , 528,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
- { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2479,9 , 4,4 , 8,6 , 531,4 , 535,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/HongKong
- { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 412,7 , 419,15 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2509,10 , 4,4 , 4,0 , 531,4 , 549,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
- { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 179,8 , 399,13 , 172,6 , 208,11 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {84,87,68}, 148,3 , 2519,10 , 4,4 , 4,0 , 531,4 , 563,2 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
- { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {72,82,75}, 151,2 , 2529,74 , 25,5 , 4,0 , 565,8 , 573,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
- { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {66,65,77}, 153,2 , 2603,106 , 25,5 , 4,0 , 565,8 , 581,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/BosniaAndHerzegowina
- { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 187,8 , 462,18 , 61,4 , 219,9 , 4747,48 , 4795,82 , 4877,24 , 4747,48 , 4901,84 , 158,27 , 2146,21 , 2167,49 , 2216,14 , 2146,21 , 2167,49 , 2216,14 , 81,4 , 80,4 , {67,90,75}, 155,2 , 2709,56 , 25,5 , 4,0 , 600,7 , 607,15 , 2, 1, 1, 6, 7 }, // Czech/Latin/CzechRepublic
- { 29, 7, 58, 44, 46, 44, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 27,8 , 480,23 , 144,5 , 149,10 , 4985,48 , 5033,84 , 134,24 , 5117,59 , 5033,84 , 134,24 , 2230,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 2765,42 , 25,5 , 4,0 , 622,5 , 627,7 , 2, 1, 1, 6, 7 }, // Danish/Latin/Denmark
- { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 14,5 , 19,6 , 634,10 , 644,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
- { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,87,71}, 159,4 , 2826,55 , 14,5 , 19,6 , 634,10 , 653,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
- { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 511,7 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 25,5 , 4,0 , 658,6 , 664,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
- { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2881,97 , 14,5 , 19,6 , 634,10 , 670,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/CuraSao
- { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {83,82,68}, 12,1 , 2978,24 , 14,5 , 19,6 , 634,10 , 677,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
- { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2881,97 , 14,5 , 19,6 , 634,10 , 685,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/SintMaarten
- { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 697,12 , 709,13 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStates
- { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 5371,80 , 5451,154 , 5605,36 , 5371,80 , 5451,154 , 5605,36 , 2452,49 , 2501,85 , 2586,21 , 2452,49 , 2501,85 , 2586,21 , 85,4 , 84,4 , {85,83,68}, 12,1 , 0,7 , 14,5 , 4,0 , 722,10 , 732,25 , 2, 1, 7, 6, 7 }, // English/Deseret/UnitedStates
- { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 764,14 , 2, 1, 7, 6, 7 }, // English/Latin/AmericanSamoa
- { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 778,19 , 2, 1, 7, 6, 7 }, // English/Latin/AntiguaAndBarbuda
- { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {65,85,68}, 12,1 , 3108,59 , 4,4 , 4,0 , 797,18 , 815,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
- { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,83,68}, 12,1 , 3167,53 , 4,4 , 8,6 , 757,7 , 824,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
- { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,66,68}, 12,1 , 3220,56 , 4,4 , 8,6 , 757,7 , 831,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
- { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 37,5 , 228,24 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 131,1 , 2807,19 , 25,5 , 4,0 , 757,7 , 839,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
- { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 524,12 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,90,68}, 12,1 , 3276,47 , 4,4 , 4,0 , 757,7 , 846,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
- { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,77,68}, 12,1 , 3323,53 , 4,4 , 8,6 , 757,7 , 852,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
- { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 3376,50 , 4,4 , 4,0 , 757,7 , 859,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
- { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 3426,50 , 4,4 , 8,6 , 757,7 , 867,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
- { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 3476,53 , 4,4 , 8,6 , 875,16 , 891,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
- { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,89,68}, 12,1 , 3529,71 , 4,4 , 8,6 , 757,7 , 897,14 , 2, 1, 1, 6, 7 }, // English/Latin/CaymanIslands
- { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 911,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
- { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {70,74,68}, 12,1 , 3600,47 , 4,4 , 8,6 , 757,7 , 919,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
- { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 757,7 , 923,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
- { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,77,68}, 172,1 , 3694,50 , 4,4 , 8,6 , 757,7 , 931,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
- { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 3744,47 , 4,4 , 8,6 , 757,7 , 937,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
- { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,73,80}, 171,1 , 3791,53 , 4,4 , 4,0 , 757,7 , 942,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
- { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 951,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
- { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 958,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
- { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,89,68}, 12,1 , 3844,56 , 4,4 , 8,6 , 757,7 , 962,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
- { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {72,75,68}, 12,1 , 3900,56 , 4,4 , 8,6 , 757,7 , 968,19 , 2, 1, 7, 6, 7 }, // English/Latin/HongKong
- { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {73,78,82}, 122,1 , 3956,44 , 14,5 , 4,0 , 757,7 , 987,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
- { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 99,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2807,19 , 4,4 , 4,0 , 757,7 , 992,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
- { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 287,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {74,77,68}, 12,1 , 4000,53 , 4,4 , 4,0 , 757,7 , 999,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
- { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,69,83}, 2,3 , 4053,53 , 4,4 , 8,6 , 757,7 , 1006,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
- { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3108,59 , 4,4 , 8,6 , 757,7 , 1011,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
- { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4106,61 , 4,4 , 8,6 , 757,7 , 1019,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
- { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 4167,53 , 4,4 , 8,6 , 757,7 , 1026,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
- { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 4220,54 , 4,4 , 8,6 , 757,7 , 1033,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
- { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,87,75}, 178,2 , 4274,53 , 4,4 , 8,6 , 757,7 , 1043,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
- { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 131,1 , 2807,19 , 4,4 , 4,0 , 757,7 , 1049,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
- { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1054,16 , 2, 1, 7, 6, 7 }, // English/Latin/MarshallIslands
- { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 4327,53 , 4,4 , 8,6 , 757,7 , 1070,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
- { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1079,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
- { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,65,68}, 12,1 , 4380,53 , 4,4 , 4,0 , 757,7 , 1089,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
- { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {78,90,68}, 12,1 , 4433,62 , 4,4 , 4,0 , 757,7 , 1096,11 , 2, 1, 7, 6, 7 }, // English/Latin/NewZealand
- { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 4495,50 , 4,4 , 8,6 , 757,7 , 1107,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
- { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1114,24 , 2, 1, 1, 6, 7 }, // English/Latin/NorthernMarianaIslands
- { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {80,75,82}, 180,2 , 4545,53 , 14,5 , 4,0 , 757,7 , 1138,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
- { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1146,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
- { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,71,75}, 139,1 , 4598,73 , 4,4 , 8,6 , 757,7 , 1151,16 , 2, 1, 1, 6, 7 }, // English/Latin/PapuaNewGuinea
- { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 4671,42 , 4,4 , 8,6 , 757,7 , 1167,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
- { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1178,11 , 2, 1, 7, 6, 7 }, // English/Latin/PuertoRico
- { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 1189,21 , 2, 1, 1, 6, 7 }, // English/Latin/SaintKittsAndNevis
- { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 1210,11 , 2, 1, 1, 6, 7 }, // English/Latin/SaintLucia
- { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 1221,32 , 2, 1, 1, 6, 7 }, // English/Latin/SaintVincentAndTheGrenadines
- { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {87,83,84}, 184,3 , 4713,40 , 4,4 , 8,6 , 757,7 , 1253,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
- { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 4753,59 , 4,4 , 8,6 , 757,7 , 1258,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
- { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,76,76}, 189,2 , 4812,68 , 4,4 , 8,6 , 757,7 , 1268,12 , 0, 0, 1, 6, 7 }, // English/Latin/SierraLeone
- { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {83,71,68}, 12,1 , 4880,56 , 4,4 , 8,6 , 757,7 , 1280,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
- { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,66,68}, 12,1 , 4936,74 , 4,4 , 8,6 , 757,7 , 1289,15 , 2, 1, 1, 6, 7 }, // English/Latin/SolomonIslands
- { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 536,10 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4106,61 , 4,4 , 8,6 , 757,7 , 1304,12 , 2, 1, 7, 6, 7 }, // English/Latin/SouthAfrica
- { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 5010,53 , 4,4 , 8,6 , 757,7 , 1316,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
- { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,90,83}, 192,3 , 5063,62 , 4,4 , 8,6 , 757,7 , 1325,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
- { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 5125,49 , 4,4 , 8,6 , 757,7 , 1333,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
- { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,84,68}, 12,1 , 5174,86 , 4,4 , 4,0 , 757,7 , 1338,19 , 2, 1, 7, 6, 7 }, // English/Latin/TrinidadAndTobago
- { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1357,24 , 2, 1, 1, 6, 7 }, // English/Latin/TurksAndCaicosIslands
- { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 5260,56 , 4,4 , 8,6 , 757,7 , 1381,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
- { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 1387,15 , 1402,14 , 2, 1, 1, 6, 7 }, // English/Latin/UnitedKingdom
- { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1416,21 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesMinorOutlyingIslands
- { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 5316,44 , 4,4 , 8,6 , 757,7 , 1437,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
- { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1444,22 , 2, 1, 1, 6, 7 }, // English/Latin/BritishVirginIslands
- { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1466,19 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesVirginIslands
- { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,77,87}, 202,2 , 5360,50 , 4,4 , 8,6 , 757,7 , 1485,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
- { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 364,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 3002,35 , 4,4 , 4,0 , 757,7 , 1491,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
- { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 757,7 , 1499,11 , 2, 1, 1, 6, 7 }, // English/Latin/IsleOfMan
- { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 757,7 , 1510,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
- { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,83,80}, 171,1 , 5410,68 , 4,4 , 8,6 , 757,7 , 1516,11 , 2, 1, 1, 6, 7 }, // English/Latin/SouthSudan
- { 33, 7, 68, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 169,8 , 169,8 , 187,8 , 462,18 , 61,4 , 252,9 , 5641,59 , 5700,91 , 5791,24 , 5641,59 , 5700,91 , 5791,24 , 2607,14 , 2621,63 , 2607,14 , 2607,14 , 2621,63 , 2607,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 5478,20 , 25,5 , 30,7 , 1527,5 , 1532,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
- { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 503,8 , 82,17 , 37,5 , 8,10 , 5815,48 , 5863,83 , 134,24 , 5815,48 , 5863,83 , 134,24 , 2684,28 , 2712,74 , 2786,14 , 2684,28 , 2712,74 , 2786,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 5498,42 , 4,4 , 43,5 , 1537,8 , 1545,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/FaroeIslands
- { 36, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 546,8 , 554,17 , 159,4 , 163,9 , 5946,69 , 6015,105 , 6120,24 , 6144,129 , 6144,129 , 6120,24 , 2800,21 , 2821,67 , 2888,14 , 2800,21 , 2902,81 , 2888,14 , 91,3 , 90,3 , {69,85,82}, 131,1 , 5540,20 , 25,5 , 4,0 , 1552,5 , 1557,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
- { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1570,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
- { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,90,68}, 207,2 , 5560,51 , 25,5 , 30,7 , 1562,8 , 1576,7 , 2, 1, 6, 4, 5 }, // French/Latin/Algeria
- { 37, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 511,7 , 99,16 , 37,5 , 261,23 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1583,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
- { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1591,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
- { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1596,12 , 0, 0, 1, 6, 7 }, // French/Latin/BurkinaFaso
- { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {66,73,70}, 212,3 , 5670,53 , 25,5 , 30,7 , 1562,8 , 1608,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
- { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1615,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
- { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 115,8 , 99,16 , 37,5 , 228,24 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 5779,54 , 25,5 , 30,7 , 1623,17 , 891,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
- { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1640,25 , 0, 0, 1, 6, 7 }, // French/Latin/CentralAfricanRepublic
- { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1665,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
- { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {75,77,70}, 215,2 , 5833,51 , 25,5 , 30,7 , 1562,8 , 1670,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
- { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,68,70}, 217,2 , 5884,53 , 25,5 , 30,7 , 1562,8 , 1677,32 , 2, 1, 1, 6, 7 }, // French/Latin/CongoKinshasa
- { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1709,17 , 0, 0, 1, 6, 7 }, // French/Latin/CongoBrazzaville
- { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1726,13 , 0, 0, 1, 6, 7 }, // French/Latin/IvoryCoast
- { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,74,70}, 5,3 , 5937,57 , 25,5 , 30,7 , 1562,8 , 1739,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
- { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1747,18 , 0, 0, 1, 6, 7 }, // French/Latin/EquatorialGuinea
- { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1765,16 , 2, 1, 1, 6, 7 }, // French/Latin/FrenchGuiana
- { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 5994,35 , 25,5 , 30,7 , 1562,8 , 1781,19 , 0, 0, 1, 6, 7 }, // French/Latin/FrenchPolynesia
- { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1800,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
- { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1805,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
- { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {71,78,70}, 223,2 , 6029,48 , 25,5 , 30,7 , 1562,8 , 1815,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
- { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {72,84,71}, 225,1 , 6077,57 , 25,5 , 30,7 , 1562,8 , 1821,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
- { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1826,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
- { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 6134,54 , 25,5 , 30,7 , 1562,8 , 1033,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
- { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1836,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
- { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1840,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
- { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,82,79}, 226,2 , 6188,66 , 25,5 , 30,7 , 1562,8 , 1850,10 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritania
- { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 6254,63 , 25,5 , 30,7 , 1562,8 , 1860,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
- { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1867,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
- { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1874,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
- { 37, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,65,68}, 0,0 , 6317,54 , 25,5 , 30,7 , 1562,8 , 1880,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
- { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 5994,35 , 25,5 , 30,7 , 1562,8 , 1885,18 , 0, 0, 1, 6, 7 }, // French/Latin/NewCaledonia
- { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1903,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
- { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1908,7 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
- { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 6371,50 , 25,5 , 30,7 , 1562,8 , 1915,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
- { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1921,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
- { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 6421,71 , 25,5 , 30,7 , 1562,8 , 1258,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
- { 37, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 187,8 , 10,17 , 37,5 , 284,14 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 6492,45 , 14,5 , 48,5 , 1928,15 , 1943,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
- { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,89,80}, 233,2 , 6537,51 , 25,5 , 30,7 , 1562,8 , 1949,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
- { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1954,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
- { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {84,78,68}, 235,2 , 6588,51 , 25,5 , 30,7 , 1562,8 , 1958,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
- { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 6639,51 , 25,5 , 30,7 , 1562,8 , 1437,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
- { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1965,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
- { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1981,31 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
- { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 185,11 , 196,10 , 141,10 , 10,17 , 37,5 , 8,10 , 6421,61 , 6482,142 , 6624,36 , 6421,61 , 6482,142 , 6624,36 , 3084,28 , 3112,69 , 3181,14 , 3084,28 , 3112,69 , 3181,14 , 0,2 , 0,2 , {71,66,80}, 171,1 , 6690,22 , 4,4 , 8,6 , 2012,8 , 2020,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/UnitedKingdom
- { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 82,17 , 37,5 , 8,10 , 6660,48 , 6708,87 , 6795,24 , 6660,48 , 6708,87 , 6795,24 , 3195,28 , 3223,49 , 3272,14 , 3195,28 , 3223,49 , 3272,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 6712,20 , 4,4 , 8,6 , 2042,6 , 2048,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
- { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 213,8 , 213,8 , 187,8 , 571,19 , 37,5 , 8,10 , 6819,48 , 6867,99 , 6966,24 , 6819,48 , 6867,99 , 6966,24 , 3286,28 , 3314,62 , 3376,14 , 3286,28 , 3314,62 , 3376,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 6732,19 , 25,5 , 4,0 , 2054,7 , 2061,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
- { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 25,5 , 4,0 , 2071,7 , 2078,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
- { 42, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 590,19 , 37,5 , 8,10 , 7180,48 , 7038,83 , 134,24 , 7228,58 , 7286,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 14,5 , 4,0 , 2089,24 , 2113,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
- { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 25,5 , 4,0 , 2071,7 , 2123,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
- { 42, 7, 123, 46, 39, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 0,0 , 6770,58 , 14,5 , 4,0 , 2071,7 , 2130,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
- { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 25,5 , 4,0 , 2071,7 , 2143,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
- { 42, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 230,3 , 6770,58 , 14,5 , 48,5 , 2152,21 , 2173,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
- { 43, 16, 85, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 131,1 , 6828,19 , 25,5 , 4,0 , 2180,8 , 2188,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
- { 43, 16, 56, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 131,1 , 6828,19 , 4,4 , 4,0 , 2180,8 , 2194,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
- { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 239,11 , 239,11 , 72,10 , 82,17 , 18,7 , 25,12 , 4985,48 , 7723,96 , 134,24 , 4985,48 , 7723,96 , 134,24 , 3610,28 , 3638,98 , 3736,14 , 3610,28 , 3638,98 , 3736,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 6847,59 , 4,4 , 43,5 , 2200,11 , 2211,16 , 2, 1, 1, 6, 7 }, // Greenlandic/Latin/Greenland
- { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 250,9 , 250,9 , 609,7 , 224,18 , 298,8 , 306,13 , 7819,64 , 7883,87 , 7970,31 , 8001,67 , 8068,87 , 7970,31 , 3750,32 , 3782,53 , 3835,19 , 3750,32 , 3782,53 , 3835,19 , 0,2 , 0,2 , {73,78,82}, 122,1 , 6906,20 , 4,4 , 8,6 , 2227,7 , 2234,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
- { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 6926,12 , 14,5 , 4,0 , 2238,5 , 2243,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
- { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 0,7 , 14,5 , 4,0 , 2238,5 , 2251,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
- { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 6938,36 , 14,5 , 4,0 , 2238,5 , 2255,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
- { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 34, 34, 39, 39, 0,6 , 0,6 , 259,6 , 259,6 , 27,8 , 616,18 , 37,5 , 8,10 , 8312,58 , 8370,72 , 158,27 , 8442,48 , 8370,72 , 158,27 , 3941,46 , 3987,65 , 4052,19 , 3941,46 , 3987,65 , 4071,21 , 103,6 , 103,5 , {73,76,83}, 52,1 , 6974,54 , 25,5 , 4,0 , 2260,5 , 2265,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
- { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 265,9 , 274,8 , 634,6 , 10,17 , 18,7 , 25,12 , 8490,75 , 8490,75 , 8565,30 , 8490,75 , 8490,75 , 8565,30 , 4092,38 , 4130,57 , 4187,19 , 4092,38 , 4130,57 , 4187,19 , 109,9 , 108,7 , {73,78,82}, 122,1 , 7028,19 , 14,5 , 4,0 , 2270,6 , 2276,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
- { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 282,8 , 282,8 , 640,11 , 651,19 , 61,4 , 219,9 , 8595,64 , 8659,98 , 8757,25 , 8595,64 , 8659,98 , 8782,25 , 4206,19 , 4225,52 , 4277,17 , 4206,19 , 4225,52 , 4277,17 , 118,3 , 115,3 , {72,85,70}, 237,2 , 7047,20 , 25,5 , 4,0 , 2280,6 , 2286,12 , 0, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
- { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 142,8 , 142,8 , 546,8 , 462,18 , 37,5 , 8,10 , 8807,48 , 8855,82 , 8937,24 , 8807,48 , 8855,82 , 8961,24 , 4294,28 , 4322,81 , 4403,14 , 4294,28 , 4322,81 , 4417,14 , 121,4 , 118,4 , {73,83,75}, 157,2 , 7067,49 , 4,4 , 8,6 , 2298,8 , 2306,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
- { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 27,8 , 123,18 , 144,5 , 149,10 , 8985,48 , 9033,87 , 134,24 , 8985,48 , 9033,87 , 134,24 , 4431,28 , 4459,43 , 4502,14 , 4431,28 , 4459,43 , 4502,14 , 0,2 , 0,2 , {73,68,82}, 239,2 , 7116,23 , 4,4 , 4,0 , 2312,16 , 2328,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
- { 53, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 9120,48 , 9168,93 , 158,27 , 9120,48 , 9168,93 , 158,27 , 4516,28 , 4544,57 , 85,14 , 4516,28 , 4544,57 , 85,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 7139,12 , 14,5 , 4,0 , 2337,11 , 2348,7 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France
- { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 9261,62 , 9323,107 , 9430,24 , 9261,62 , 9323,107 , 9430,24 , 4601,37 , 4638,75 , 4713,14 , 4601,37 , 4638,75 , 4713,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 7151,11 , 4,4 , 4,0 , 2355,7 , 2362,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
- { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 14,5 , 4,0 , 2366,8 , 2374,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
- { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 14,5 , 4,0 , 2366,8 , 2380,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/SanMarino
- { 58, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 309,8 , 206,7 , 187,8 , 10,17 , 37,5 , 284,14 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 7162,53 , 14,5 , 48,5 , 2366,8 , 2390,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
- { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 125,5 , 125,5 , 536,10 , 399,13 , 61,4 , 319,10 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 4883,14 , 4897,28 , 4883,14 , 4883,14 , 4897,28 , 4883,14 , 125,2 , 122,2 , {74,80,89}, 143,1 , 7215,10 , 4,4 , 4,0 , 2398,3 , 2401,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
- { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 3208, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 317,12 , 329,11 , 634,6 , 99,16 , 298,8 , 306,13 , 9714,91 , 9805,86 , 9891,31 , 9714,91 , 9805,86 , 9922,31 , 4925,28 , 4953,53 , 5006,19 , 4925,28 , 4953,53 , 5006,19 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7225,20 , 4,4 , 8,6 , 2403,5 , 2408,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
- { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 9953,72 , 9953,72 , 10025,24 , 9953,72 , 9953,72 , 10025,24 , 5025,54 , 5079,56 , 5135,14 , 5025,54 , 5079,56 , 5135,14 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7245,23 , 14,5 , 4,0 , 2412,5 , 2417,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
- { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10049,61 , 10110,83 , 158,27 , 10049,61 , 10110,83 , 158,27 , 5149,28 , 5177,54 , 85,14 , 5149,28 , 5177,54 , 85,14 , 0,2 , 0,2 , {75,90,84}, 241,1 , 7268,24 , 25,5 , 4,0 , 2427,10 , 2437,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
- { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 10193,60 , 10253,101 , 158,27 , 10193,60 , 10253,101 , 158,27 , 5231,35 , 5266,84 , 85,14 , 5231,35 , 5266,84 , 85,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 0,7 , 14,5 , 4,0 , 2446,11 , 1915,6 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
- { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10354,60 , 10414,80 , 158,27 , 10494,59 , 10553,80 , 158,27 , 5350,28 , 5378,57 , 85,14 , 5435,28 , 5463,57 , 85,14 , 0,2 , 0,2 , {75,71,83}, 242,3 , 0,7 , 14,5 , 4,0 , 2457,6 , 2463,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
- { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,82,87}, 245,1 , 7292,13 , 4,4 , 8,6 , 2473,3 , 2476,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/SouthKorea
- { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,80,87}, 0,0 , 7305,23 , 4,4 , 8,6 , 2473,3 , 2480,14 , 0, 0, 1, 6, 7 }, // Korean/Korean/NorthKorea
- { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 10672,60 , 10732,106 , 158,27 , 10672,60 , 10732,106 , 158,27 , 5562,34 , 5596,89 , 85,14 , 5562,34 , 5596,89 , 85,14 , 129,5 , 126,5 , {66,73,70}, 212,3 , 7328,27 , 0,4 , 4,0 , 2494,8 , 2502,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
- { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 717,18 , 61,4 , 349,24 , 10838,62 , 10900,75 , 158,27 , 10975,61 , 10900,75 , 158,27 , 5685,23 , 5708,57 , 5765,18 , 5783,24 , 5708,57 , 1765,14 , 134,8 , 131,8 , {76,65,75}, 246,1 , 7355,14 , 4,4 , 48,5 , 2510,3 , 2513,9 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
- { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 347,8 , 347,8 , 187,8 , 735,26 , 37,5 , 8,10 , 11036,65 , 11101,101 , 134,24 , 11202,65 , 11267,101 , 134,24 , 5807,21 , 5828,72 , 5900,14 , 5807,21 , 5914,72 , 5900,14 , 142,14 , 139,11 , {76,86,76}, 247,2 , 7369,59 , 4,4 , 8,6 , 2522,8 , 2530,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
- { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {67,68,70}, 217,2 , 7428,23 , 25,5 , 4,0 , 2537,7 , 2544,29 , 2, 1, 1, 6, 7 }, // Lingala/Latin/CongoKinshasa
- { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {65,79,65}, 249,2 , 7451,23 , 25,5 , 4,0 , 2537,7 , 2573,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
- { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 36,4 , 7474,23 , 25,5 , 4,0 , 2537,7 , 2579,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CentralAfricanRepublic
- { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 36,4 , 7474,23 , 25,5 , 4,0 , 2537,7 , 2605,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CongoBrazzaville
- { 73, 7, 124, 44, 160, 59, 37, 48, 8211, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 364,8 , 364,8 , 72,10 , 761,27 , 37,5 , 8,10 , 11643,70 , 11713,96 , 11809,24 , 11643,70 , 11713,96 , 11809,24 , 6128,21 , 6149,89 , 6238,14 , 6128,21 , 6149,89 , 6238,14 , 164,9 , 156,6 , {76,84,76}, 251,2 , 7497,62 , 25,5 , 4,0 , 2610,8 , 2618,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
- { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 788,7 , 123,18 , 37,5 , 8,10 , 11833,63 , 11896,85 , 11981,24 , 11833,63 , 11896,85 , 11981,24 , 6252,34 , 6286,54 , 1521,14 , 6252,34 , 6286,54 , 1521,14 , 173,10 , 162,8 , {77,75,68}, 253,3 , 7559,23 , 14,5 , 4,0 , 2625,10 , 2635,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
- { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 12005,48 , 12053,92 , 134,24 , 12005,48 , 12053,92 , 134,24 , 6340,34 , 6374,60 , 6434,14 , 6340,34 , 6374,60 , 6434,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 7582,13 , 4,4 , 4,0 , 2645,8 , 2653,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
- { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {77,89,82}, 256,2 , 7595,23 , 4,4 , 8,6 , 2665,13 , 2678,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
- { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 524,12 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {66,78,68}, 12,1 , 7618,19 , 14,5 , 4,0 , 2665,13 , 2686,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
- { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {83,71,68}, 12,1 , 7637,22 , 4,4 , 8,6 , 2665,13 , 2692,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
- { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 372,13 , 385,12 , 27,8 , 795,18 , 18,7 , 25,12 , 12300,62 , 12362,87 , 12449,31 , 12300,62 , 12362,87 , 12449,31 , 6533,41 , 6574,70 , 6644,22 , 6533,41 , 6574,70 , 6644,22 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7659,40 , 0,4 , 4,0 , 2701,6 , 2707,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
- { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 397,8 , 405,7 , 141,10 , 813,23 , 37,5 , 8,10 , 12480,48 , 12528,86 , 12614,24 , 12480,48 , 12528,86 , 12614,24 , 6666,28 , 6694,63 , 6757,14 , 6666,28 , 6694,63 , 6757,14 , 185,2 , 173,2 , {69,85,82}, 131,1 , 7699,11 , 4,4 , 4,0 , 2713,5 , 1049,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
- { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 412,9 , 412,9 , 634,6 , 99,16 , 373,7 , 380,12 , 12638,66 , 12704,86 , 12790,32 , 12638,66 , 12704,86 , 12790,32 , 6771,32 , 6803,53 , 4187,19 , 6771,32 , 6803,53 , 4187,19 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7710,19 , 4,4 , 8,6 , 2718,5 , 2276,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
- { 82, 2, 143, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 836,31 , 37,5 , 8,10 , 12822,48 , 12870,66 , 158,27 , 12822,48 , 12870,66 , 158,27 , 6856,21 , 6877,43 , 1765,14 , 6856,21 , 6877,43 , 1765,14 , 187,2 , 175,2 , {77,78,84}, 258,1 , 7729,25 , 14,5 , 4,0 , 2723,6 , 2729,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
- { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 12992,85 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 6953,54 , 7007,14 , 189,14 , 177,14 , {78,80,82}, 259,4 , 7754,52 , 14,5 , 4,0 , 2735,6 , 2741,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
- { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 13104,80 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 7021,54 , 7007,14 , 109,9 , 108,7 , {73,78,82}, 122,1 , 7806,49 , 14,5 , 4,0 , 2735,6 , 2276,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
- { 85, 7, 161, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 7075,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 7855,44 , 14,5 , 4,0 , 2746,12 , 2758,5 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/Norway
- { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 10,17 , 18,7 , 25,12 , 13326,89 , 13326,89 , 13415,32 , 13326,89 , 13326,89 , 13415,32 , 7103,33 , 7136,54 , 7190,18 , 7103,33 , 7136,54 , 7190,18 , 89,2 , 88,2 , {73,78,82}, 122,1 , 7899,11 , 14,5 , 4,0 , 2763,5 , 2768,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
- { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 867,20 , 61,4 , 408,11 , 13447,68 , 13447,68 , 158,27 , 13447,68 , 13447,68 , 158,27 , 7208,49 , 7208,49 , 85,14 , 7208,49 , 7208,49 , 85,14 , 203,4 , 191,4 , {65,70,78}, 263,1 , 7910,13 , 25,5 , 4,0 , 2772,4 , 2776,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
- { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13585,24 , 13609,74 , 13609,74 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {73,82,82}, 264,1 , 7923,17 , 53,5 , 58,7 , 2785,5 , 2790,5 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Iran
- { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13683,24 , 13707,64 , 13771,68 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {65,70,78}, 263,1 , 7940,23 , 53,5 , 58,7 , 2795,3 , 2776,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
- { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 887,10 , 10,17 , 37,5 , 8,10 , 13839,48 , 13887,97 , 13984,24 , 13839,48 , 14008,99 , 13984,24 , 7271,34 , 7305,59 , 7364,14 , 7271,34 , 7305,59 , 7364,14 , 0,2 , 0,2 , {80,76,78}, 265,2 , 7963,77 , 25,5 , 30,7 , 2798,6 , 2804,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
- { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14107,48 , 14155,89 , 134,24 , 14107,48 , 14155,89 , 134,24 , 7378,28 , 7406,79 , 7485,14 , 7378,28 , 7406,79 , 7485,14 , 0,2 , 0,2 , {66,82,76}, 267,2 , 8040,54 , 4,4 , 8,6 , 2810,19 , 2829,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
- { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {65,79,65}, 249,2 , 8094,54 , 25,5 , 4,0 , 2835,9 , 2844,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
- { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {67,86,69}, 0,0 , 8148,69 , 25,5 , 4,0 , 2835,9 , 2850,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/CapeVerde
- { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 8217,81 , 25,5 , 4,0 , 2835,9 , 2860,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/EastTimor
- { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 8298,62 , 25,5 , 4,0 , 2835,9 , 2871,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/GuineaBissau
- { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,79,80}, 144,4 , 8360,53 , 25,5 , 4,0 , 2835,9 , 2883,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
- { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 8413,72 , 25,5 , 4,0 , 2835,9 , 2902,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
- { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 8485,20 , 25,5 , 4,0 , 2912,17 , 2929,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
- { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {83,84,68}, 272,2 , 8505,92 , 25,5 , 4,0 , 2835,9 , 2937,19 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/SaoTomeAndPrincipe
- { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 39, 39, 34, 34, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14381,68 , 14381,68 , 14449,27 , 14381,68 , 14381,68 , 14449,27 , 7578,38 , 7616,55 , 7671,23 , 7578,38 , 7616,55 , 7671,23 , 216,11 , 203,11 , {73,78,82}, 122,1 , 8597,12 , 14,5 , 4,0 , 2956,6 , 2962,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
- { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14476,67 , 14476,67 , 158,27 , 14476,67 , 14476,67 , 158,27 , 7694,37 , 7694,37 , 85,14 , 7694,37 , 7694,37 , 85,14 , 0,2 , 0,2 , {80,75,82}, 274,1 , 8609,13 , 14,5 , 4,0 , 2966,5 , 2971,6 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
- { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 503,8 , 924,28 , 37,5 , 8,10 , 14543,67 , 14610,92 , 14702,24 , 14543,67 , 14610,92 , 14702,24 , 7731,23 , 7754,56 , 7810,14 , 7731,23 , 7754,56 , 7810,14 , 89,2 , 214,2 , {67,72,70}, 230,3 , 8622,20 , 25,5 , 4,0 , 2977,9 , 2986,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
- { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {82,79,78}, 0,0 , 8642,57 , 25,5 , 4,0 , 2992,6 , 2998,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
- { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {77,68,76}, 0,0 , 8699,69 , 25,5 , 4,0 , 2992,6 , 3005,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
- { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {82,85,66}, 275,4 , 8768,89 , 25,5 , 4,0 , 3022,7 , 3029,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
- { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {66,89,82}, 140,2 , 8857,94 , 25,5 , 4,0 , 3022,7 , 464,8 , 0, 0, 7, 6, 7 }, // Russian/Cyrillic/Belarus
- { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,90,84}, 241,1 , 8951,83 , 25,5 , 4,0 , 3022,7 , 3035,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
- { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,71,83}, 242,3 , 9034,81 , 25,5 , 4,0 , 3022,7 , 3044,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
- { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {77,68,76}, 0,0 , 9115,79 , 25,5 , 4,0 , 3022,7 , 3052,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
- { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 37,5 , 8,10 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {85,65,72}, 279,1 , 9194,92 , 25,5 , 4,0 , 3022,7 , 3059,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
- { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 15139,48 , 15187,91 , 15278,24 , 15139,48 , 15187,91 , 15278,24 , 8073,28 , 8101,66 , 8167,14 , 8073,28 , 8101,66 , 8167,14 , 237,2 , 229,2 , {88,65,70}, 36,4 , 9286,25 , 4,4 , 48,5 , 3066,5 , 3071,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/CentralAfricanRepublic
- { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {82,83,68}, 280,4 , 9311,72 , 25,5 , 4,0 , 3093,6 , 3099,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
- { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 115,8 , 981,20 , 37,5 , 419,40 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15431,83 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8275,28 , 8303,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 284,2 , 9383,196 , 25,5 , 4,0 , 3105,6 , 3111,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/BosniaAndHerzegowina
- { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 131,1 , 9579,27 , 25,5 , 4,0 , 3093,6 , 3130,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
- { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15514,48 , 15562,81 , 15643,24 , 15514,48 , 15562,81 , 15643,24 , 8357,28 , 8385,54 , 2118,14 , 8357,28 , 8385,54 , 2118,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 9606,196 , 25,5 , 4,0 , 3139,6 , 581,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/BosniaAndHerzegowina
- { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15514,48 , 15562,81 , 15643,24 , 15514,48 , 15562,81 , 15643,24 , 8357,28 , 8385,54 , 2118,14 , 8357,28 , 8385,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 131,1 , 9802,27 , 25,5 , 4,0 , 3139,6 , 3145,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
- { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15514,48 , 15562,81 , 15643,24 , 15514,48 , 15562,81 , 15643,24 , 8357,28 , 8385,54 , 2118,14 , 8357,28 , 8385,54 , 2118,14 , 248,9 , 238,7 , {82,83,68}, 286,4 , 9829,72 , 25,5 , 4,0 , 3139,6 , 3154,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
- { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 9901,17 , 14,5 , 4,0 , 3160,4 , 3164,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
- { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 9918,17 , 14,5 , 4,0 , 3160,4 , 3175,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
- { 102, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3181,7 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/SouthAfrica
- { 102, 7, 120, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3181,7 , 0,0 , 2, 1, 1, 6, 7 }, // Southern Sotho/Latin/Lesotho
- { 103, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3188,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/SouthAfrica
- { 103, 7, 28, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 0,7 , 4,4 , 4,0 , 3188,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/Botswana
- { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 16212,47 , 16259,100 , 16359,24 , 16212,47 , 16259,100 , 16359,24 , 8810,32 , 8842,55 , 8897,14 , 8810,32 , 8842,55 , 8897,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 9935,22 , 4,4 , 8,6 , 3196,8 , 1491,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
- { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 536,10 , 323,17 , 459,7 , 466,13 , 16383,59 , 16442,96 , 16538,32 , 16570,61 , 16442,96 , 16538,32 , 8911,30 , 8941,62 , 9003,19 , 8911,30 , 8941,62 , 9003,19 , 257,5 , 245,4 , {76,75,82}, 290,3 , 9957,19 , 14,5 , 4,0 , 3204,5 , 3209,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/SriLanka
- { 107, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3220,7 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/SouthAfrica
- { 107, 7, 204, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 0,7 , 4,4 , 4,0 , 3220,7 , 0,0 , 2, 1, 1, 6, 7 }, // Swati/Latin/Swaziland
- { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 546,8 , 462,18 , 61,4 , 219,9 , 16793,48 , 16841,82 , 15643,24 , 16793,48 , 16923,89 , 15643,24 , 9117,21 , 9138,52 , 9190,14 , 9117,21 , 9138,52 , 9190,14 , 262,10 , 249,9 , {69,85,82}, 131,1 , 9976,28 , 25,5 , 4,0 , 3227,10 , 3237,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
- { 109, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 445,8 , 445,8 , 1024,9 , 590,19 , 37,5 , 8,10 , 15514,48 , 17012,86 , 15643,24 , 17098,59 , 17012,86 , 15643,24 , 9204,28 , 9232,52 , 9284,14 , 9298,35 , 9232,52 , 9284,14 , 81,4 , 258,4 , {69,85,82}, 131,1 , 10004,28 , 4,4 , 8,6 , 3246,11 , 3257,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
- { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {83,79,83}, 98,1 , 10032,22 , 4,4 , 4,0 , 3266,8 , 3274,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
- { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {68,74,70}, 5,3 , 10054,21 , 4,4 , 4,0 , 3266,8 , 3284,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
- { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {69,84,66}, 0,2 , 10075,22 , 4,4 , 4,0 , 3266,8 , 3291,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
- { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3266,8 , 3299,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
- { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 3306,17 , 2048,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
- { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 479,14 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {65,82,83}, 12,1 , 10097,51 , 4,4 , 4,0 , 3323,7 , 3330,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
- { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {66,79,66}, 293,2 , 10148,35 , 4,4 , 4,0 , 3323,7 , 3339,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
- { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 503,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,76,80}, 12,1 , 10183,45 , 4,4 , 48,5 , 3323,7 , 3346,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
- { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,79,80}, 12,1 , 10228,54 , 4,4 , 4,0 , 3323,7 , 3351,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
- { 111, 7, 52, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,82,67}, 295,1 , 10282,67 , 4,4 , 4,0 , 3323,7 , 3359,10 , 0, 0, 1, 6, 7 }, // Spanish/Latin/CostaRica
- { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,85,80}, 12,1 , 10349,42 , 4,4 , 4,0 , 3323,7 , 3369,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
- { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {68,79,80}, 12,1 , 10391,54 , 4,4 , 4,0 , 3323,7 , 3373,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/DominicanRepublic
- { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 48,5 , 3323,7 , 3393,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
- { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 204,3 , 10445,70 , 4,4 , 4,0 , 3323,7 , 3400,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/ElSalvador
- { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {88,65,70}, 36,4 , 10515,53 , 4,4 , 4,0 , 3323,7 , 3411,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/EquatorialGuinea
- { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {71,84,81}, 296,1 , 10568,70 , 4,4 , 4,0 , 3323,7 , 3428,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
- { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 1033,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {72,78,76}, 297,1 , 10638,60 , 4,4 , 4,0 , 3323,7 , 3437,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
- { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {77,88,78}, 12,1 , 10698,48 , 4,4 , 4,0 , 3323,7 , 3445,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
- { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {78,73,79}, 298,2 , 10746,69 , 4,4 , 4,0 , 3323,7 , 3451,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
- { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,65,66}, 300,3 , 10815,54 , 4,4 , 4,0 , 3323,7 , 3460,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
- { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,89,71}, 303,1 , 10869,61 , 14,5 , 65,6 , 3323,7 , 3466,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
- { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 493,15 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,69,78}, 304,3 , 10930,62 , 4,4 , 4,0 , 3323,7 , 3474,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
- { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {80,72,80}, 183,1 , 10992,48 , 25,5 , 4,0 , 3323,7 , 3478,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
- { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3323,7 , 1178,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/PuertoRico
- { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 518,6 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3323,7 , 3487,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/UnitedStates
- { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,89,85}, 12,1 , 11040,48 , 14,5 , 71,7 , 3323,7 , 3501,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
- { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {86,69,70}, 307,3 , 11088,64 , 4,4 , 48,5 , 3323,7 , 3508,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela
- { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 3323,7 , 3517,14 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CanaryIslands
- { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {0,0,0}, 0,0 , 11152,0 , 4,4 , 4,0 , 3531,23 , 3554,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/LatinAmericaAndTheCaribbean
- { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 3323,7 , 3567,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CeutaAndMelilla
- { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {84,90,83}, 192,3 , 11152,27 , 4,4 , 8,6 , 3582,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
- { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {75,69,83}, 2,3 , 11179,24 , 4,4 , 4,0 , 3582,9 , 1006,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
- { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {85,71,88}, 197,3 , 11203,25 , 4,4 , 8,6 , 3582,9 , 1381,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
- { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {83,69,75}, 157,2 , 11228,45 , 25,5 , 4,0 , 3591,7 , 3598,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Sweden
- { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 131,1 , 11273,19 , 25,5 , 4,0 , 3591,7 , 3605,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
- { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 131,1 , 11273,19 , 25,5 , 4,0 , 3591,7 , 3612,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/AlandIslands
- { 116, 2, 209, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 171, 8222, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 158,27 , 17980,48 , 18028,71 , 158,27 , 9770,28 , 9798,55 , 85,14 , 9770,28 , 9798,55 , 85,14 , 0,2 , 0,2 , {84,74,83}, 242,3 , 11292,13 , 14,5 , 4,0 , 3617,6 , 3623,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
- { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {73,78,82}, 122,1 , 11305,13 , 14,5 , 4,0 , 3633,5 , 3638,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
- { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {77,89,82}, 256,2 , 11318,22 , 14,5 , 4,0 , 3633,5 , 3645,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
- { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {83,71,68}, 12,1 , 11340,24 , 14,5 , 4,0 , 3633,5 , 3652,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
- { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {76,75,82}, 310,3 , 11364,20 , 14,5 , 4,0 , 3633,5 , 3663,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/SriLanka
- { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 499,11 , 499,11 , 503,8 , 99,16 , 18,7 , 25,12 , 18360,66 , 18426,86 , 18512,31 , 18543,78 , 18426,86 , 18621,31 , 9922,32 , 9954,60 , 10014,18 , 9922,32 , 9954,60 , 10014,18 , 0,2 , 0,2 , {73,78,82}, 122,1 , 11384,26 , 4,4 , 8,6 , 3669,6 , 3675,9 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
- { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 510,5 , 510,5 , 515,8 , 523,7 , 287,6 , 1098,19 , 37,5 , 508,28 , 18652,63 , 18715,98 , 18652,63 , 18652,63 , 18715,98 , 18813,62 , 10032,23 , 10055,68 , 10032,23 , 10032,23 , 10055,68 , 10032,23 , 284,10 , 274,10 , {84,72,66}, 313,1 , 11410,13 , 4,4 , 8,6 , 3684,3 , 3684,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
- { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {67,78,89}, 314,1 , 11423,13 , 14,5 , 4,0 , 3687,8 , 3695,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
- { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {73,78,82}, 122,1 , 11436,22 , 14,5 , 4,0 , 3687,8 , 3701,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
- { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1117,23 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 10292,29 , 10292,29 , 10321,14 , 10292,29 , 10292,29 , 10321,14 , 301,7 , 292,7 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 3708,4 , 103,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
- { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1140,23 , 18,7 , 25,12 , 19141,46 , 19187,54 , 1050,24 , 19141,46 , 19187,54 , 1050,24 , 10335,29 , 10335,29 , 10321,14 , 10335,29 , 10335,29 , 10321,14 , 301,7 , 292,7 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 3708,4 , 3712,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
- { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 530,8 , 530,8 , 530,8 , 530,8 , 287,6 , 99,16 , 37,5 , 8,10 , 19241,51 , 19292,87 , 19379,24 , 19241,51 , 19292,87 , 19379,24 , 10364,29 , 10393,60 , 10453,14 , 10364,29 , 10393,60 , 10453,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 0,7 , 14,5 , 4,0 , 3716,13 , 1333,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
- { 124, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 19403,48 , 19451,122 , 158,27 , 19403,48 , 19451,122 , 158,27 , 10467,27 , 10494,72 , 85,14 , 10467,27 , 10494,72 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3729,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/SouthAfrica
- { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {84,82,89}, 315,1 , 11474,18 , 25,5 , 30,7 , 3737,6 , 3743,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
- { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {69,85,82}, 131,1 , 7151,11 , 25,5 , 30,7 , 3737,6 , 3750,23 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
- { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 546,8 , 546,8 , 187,8 , 1188,22 , 37,5 , 8,10 , 19720,48 , 19768,95 , 19863,24 , 19887,67 , 19954,87 , 19863,24 , 10662,21 , 10683,56 , 10739,14 , 10662,21 , 10683,56 , 10739,14 , 310,2 , 301,2 , {85,65,72}, 279,1 , 11492,49 , 25,5 , 4,0 , 3773,10 , 3783,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
- { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {80,75,82}, 180,2 , 11541,21 , 4,4 , 4,0 , 3790,4 , 3794,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
- { 130, 1, 100, 46, 44, 59, 37, 1776, 45, 43, 1602, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {73,78,82}, 122,1 , 11562,18 , 14,5 , 4,0 , 3790,4 , 3801,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
- { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 14970,24 , 17980,48 , 18028,71 , 14970,24 , 10789,28 , 10817,53 , 10870,14 , 10789,28 , 10817,53 , 10870,14 , 0,2 , 0,2 , {85,90,83}, 316,3 , 11580,21 , 14,5 , 4,0 , 3806,5 , 3811,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
- { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 1210,33 , 61,4 , 408,11 , 20107,48 , 13771,68 , 158,27 , 20107,48 , 13771,68 , 158,27 , 10884,21 , 7208,49 , 85,14 , 10884,21 , 7208,49 , 85,14 , 0,2 , 0,2 , {65,70,78}, 263,1 , 11601,13 , 25,5 , 4,0 , 3821,6 , 2776,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
- { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 20155,52 , 20207,77 , 20284,24 , 20155,52 , 20207,77 , 20284,24 , 10905,34 , 10939,61 , 11000,14 , 10905,34 , 10939,61 , 11000,14 , 0,2 , 0,2 , {85,90,83}, 319,4 , 11614,23 , 14,5 , 4,0 , 3827,9 , 3836,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
- { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 573,8 , 573,8 , 141,10 , 1243,31 , 37,5 , 8,10 , 20308,75 , 20383,130 , 158,27 , 20308,75 , 20383,130 , 158,27 , 11014,33 , 11047,55 , 11102,21 , 11014,33 , 11047,55 , 11102,21 , 321,2 , 312,2 , {86,78,68}, 323,1 , 11637,20 , 25,5 , 4,0 , 3847,10 , 3857,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
- { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 135,7 , 135,7 , 141,10 , 10,17 , 37,5 , 8,10 , 20513,52 , 20565,87 , 20652,26 , 20678,62 , 20565,87 , 20652,26 , 11123,29 , 11152,77 , 11229,15 , 11244,30 , 11152,77 , 11229,15 , 0,2 , 0,2 , {71,66,80}, 171,1 , 11657,154 , 4,4 , 4,0 , 3865,7 , 3872,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/UnitedKingdom
- { 136, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 20740,48 , 20788,91 , 158,27 , 20740,48 , 20788,91 , 158,27 , 11274,28 , 11302,61 , 85,14 , 11274,28 , 11302,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3888,8 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/SouthAfrica
- { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 20879,73 , 20952,121 , 158,27 , 20879,73 , 20952,121 , 158,27 , 11363,44 , 11407,69 , 85,14 , 11363,44 , 11407,69 , 85,14 , 323,5 , 314,5 , {78,71,78}, 182,1 , 11811,34 , 4,4 , 8,6 , 3896,10 , 3906,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
- { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 581,9 , 590,10 , 72,10 , 82,17 , 18,7 , 25,12 , 21073,48 , 21121,104 , 134,24 , 21073,48 , 21225,90 , 134,24 , 11476,28 , 11504,68 , 11572,14 , 11476,28 , 11504,68 , 11572,14 , 328,7 , 319,8 , {90,65,82}, 11,1 , 11845,27 , 4,4 , 8,6 , 3924,7 , 3931,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/SouthAfrica
- { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 11586,28 , 11614,51 , 2309,14 , 11665,28 , 11614,51 , 2309,14 , 335,9 , 327,11 , {78,79,75}, 157,2 , 11872,42 , 25,5 , 4,0 , 3948,7 , 3955,5 , 2, 1, 1, 6, 7 }, // NorwegianNynorsk/Latin/Norway
- { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 118,7 , 118,7 , 1274,9 , 981,20 , 37,5 , 8,10 , 15514,48 , 21315,83 , 15643,24 , 15514,48 , 21315,83 , 15643,24 , 2032,28 , 2060,58 , 85,14 , 2032,28 , 2060,58 , 85,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 11914,218 , 14,5 , 4,0 , 3960,8 , 581,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/BosniaAndHerzegowina
- { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 37,5 , 8,10 , 15302,48 , 15431,83 , 11981,24 , 15302,48 , 15431,83 , 11981,24 , 8275,28 , 8303,54 , 8261,14 , 8275,28 , 8303,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 284,2 , 12132,195 , 25,5 , 4,0 , 3968,8 , 3111,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/BosniaAndHerzegowina
- { 144, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 82,17 , 37,5 , 8,10 , 21398,102 , 21500,140 , 158,27 , 21398,102 , 21500,140 , 158,27 , 11693,30 , 11723,57 , 85,14 , 11693,30 , 11723,57 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 3976,5 , 3981,14 , 2, 1, 1, 6, 7 }, // Manx/Latin/UnitedKingdom
- { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 21640,46 , 21686,124 , 158,27 , 21640,46 , 21686,124 , 158,27 , 11780,28 , 11808,60 , 85,14 , 11780,28 , 11808,60 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 3995,8 , 3981,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/UnitedKingdom
- { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 21810,48 , 21858,192 , 158,27 , 21810,48 , 21858,192 , 158,27 , 11868,28 , 11896,49 , 11945,14 , 11868,28 , 11896,49 , 11945,14 , 344,2 , 338,2 , {71,72,83}, 173,3 , 12327,17 , 4,4 , 4,0 , 4003,4 , 4007,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
- { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 99,16 , 18,7 , 25,12 , 22050,87 , 22050,87 , 158,27 , 22050,87 , 22050,87 , 158,27 , 6771,32 , 11959,55 , 85,14 , 6771,32 , 11959,55 , 85,14 , 346,5 , 340,5 , {73,78,82}, 122,1 , 0,7 , 14,5 , 4,0 , 4012,6 , 2276,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
- { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22137,48 , 22185,86 , 158,27 , 22137,48 , 22185,86 , 158,27 , 12014,29 , 12043,57 , 85,14 , 12014,29 , 12043,57 , 85,14 , 351,4 , 345,4 , {78,71,78}, 182,1 , 12344,12 , 4,4 , 8,6 , 4018,4 , 1107,7 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
- { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22271,48 , 22319,189 , 22508,24 , 22271,48 , 22319,189 , 22508,24 , 12100,28 , 12128,74 , 12202,14 , 12100,28 , 12128,74 , 12202,14 , 355,9 , 349,7 , {75,69,83}, 2,3 , 12356,23 , 4,4 , 8,6 , 4022,7 , 1006,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
- { 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1283,22 , 18,7 , 25,12 , 22532,47 , 22579,77 , 22656,24 , 22532,47 , 22579,77 , 22656,24 , 12216,26 , 12242,43 , 12285,14 , 12216,26 , 12242,43 , 12285,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4029,3 , 3712,4 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea
- { 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1305,21 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12299,27 , 12326,41 , 12367,14 , 12299,27 , 12326,41 , 12367,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4032,3 , 3712,4 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea
- { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 1326,27 , 37,5 , 8,10 , 22680,48 , 22728,77 , 22805,24 , 22680,48 , 22728,77 , 22805,24 , 12381,28 , 12409,50 , 3070,14 , 12381,28 , 12409,50 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 14,5 , 4,0 , 4035,6 , 4041,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
- { 160, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 22829,48 , 22877,111 , 158,27 , 22829,48 , 22877,111 , 158,27 , 12459,27 , 12486,70 , 85,14 , 12459,27 , 12486,70 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4047,9 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/SouthAfrica
- { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {71,72,83}, 173,3 , 12379,37 , 4,4 , 8,6 , 4056,6 , 4062,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
- { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {88,79,70}, 209,3 , 12416,106 , 4,4 , 8,6 , 4056,6 , 4074,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
- { 162, 14, 69, 46, 8217, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1376,22 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12642,27 , 12642,27 , 12669,14 , 12642,27 , 12642,27 , 12669,14 , 0,2 , 0,2 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 4085,5 , 103,5 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia
- { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 10,17 , 18,7 , 25,12 , 23147,59 , 23206,95 , 158,27 , 23147,59 , 23206,95 , 158,27 , 12683,21 , 12704,57 , 85,14 , 12683,21 , 12704,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 0,7 , 4,4 , 8,6 , 4090,14 , 4104,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/UnitedStates
- { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 621,8 , 621,8 , 518,6 , 1398,18 , 37,5 , 8,10 , 23301,48 , 23349,88 , 23437,24 , 23301,48 , 23349,88 , 23437,24 , 12761,28 , 12789,55 , 12844,14 , 12858,28 , 12789,55 , 12844,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 12522,22 , 4,4 , 8,6 , 4123,8 , 4131,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
- { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 23461,86 , 134,24 , 6990,48 , 23461,86 , 134,24 , 12886,28 , 12914,63 , 3471,14 , 12886,28 , 12914,63 , 3471,14 , 94,5 , 361,4 , {67,72,70}, 230,3 , 12544,55 , 25,5 , 4,0 , 4140,16 , 4156,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
- { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 158,27 , 23547,38 , 158,27 , 158,27 , 23547,38 , 158,27 , 12977,21 , 12998,28 , 13026,14 , 12977,21 , 12998,28 , 13026,14 , 367,2 , 365,2 , {67,78,89}, 314,1 , 0,7 , 14,5 , 4,0 , 4163,3 , 4166,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
- { 171, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23585,48 , 23633,100 , 158,27 , 23585,48 , 23633,100 , 158,27 , 13040,27 , 13067,66 , 85,14 , 13040,27 , 13067,66 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4168,10 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/SouthAfrica
- { 172, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23733,48 , 23781,94 , 158,27 , 23733,48 , 23781,94 , 158,27 , 13133,27 , 13160,63 , 85,14 , 13133,27 , 13160,63 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4178,16 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/SouthAfrica
- { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 23875,59 , 23934,145 , 24079,24 , 23875,59 , 23934,145 , 24079,24 , 13223,33 , 13256,75 , 13331,14 , 13223,33 , 13256,75 , 13331,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 12599,63 , 25,5 , 4,0 , 4194,15 , 4209,5 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Norway
- { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 24103,85 , 23934,145 , 24079,24 , 24103,85 , 23934,145 , 24079,24 , 13223,33 , 13345,65 , 13410,14 , 13223,33 , 13345,65 , 13410,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 12662,23 , 25,5 , 4,0 , 4194,15 , 4214,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
- { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24188,48 , 24236,88 , 24324,24 , 24188,48 , 24236,88 , 24324,24 , 13424,28 , 13452,62 , 13514,14 , 13424,28 , 13452,62 , 13514,14 , 369,5 , 367,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4220,8 , 1006,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
- { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24348,48 , 24396,221 , 24617,24 , 24348,48 , 24396,221 , 24617,24 , 13528,28 , 13556,105 , 13661,14 , 13528,28 , 13556,105 , 13661,14 , 374,10 , 377,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4228,7 , 1006,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
- { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 24641,48 , 24689,77 , 24766,24 , 24641,48 , 24689,77 , 24766,24 , 13675,28 , 13703,59 , 13762,14 , 13675,28 , 13703,59 , 13762,14 , 384,6 , 387,7 , {88,79,70}, 209,3 , 12709,26 , 25,5 , 4,0 , 4235,6 , 4241,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
- { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24790,48 , 24838,185 , 25023,24 , 24790,48 , 24838,185 , 25023,24 , 13776,28 , 13804,63 , 13867,14 , 13776,28 , 13804,63 , 13867,14 , 390,6 , 394,8 , {75,69,83}, 2,3 , 12735,23 , 4,4 , 8,6 , 4249,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
- { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25047,48 , 25095,173 , 25268,24 , 25047,48 , 25095,173 , 25268,24 , 13881,28 , 13909,105 , 14014,14 , 13881,28 , 13909,105 , 14014,14 , 396,7 , 402,5 , {75,69,83}, 2,3 , 12758,25 , 4,4 , 8,6 , 4255,8 , 1006,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
- { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 897,27 , 37,5 , 8,10 , 25292,48 , 25340,88 , 134,24 , 25292,48 , 25340,88 , 134,24 , 14028,28 , 14056,55 , 14111,14 , 14028,28 , 14056,55 , 14111,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 12783,28 , 0,4 , 4,0 , 4263,4 , 2902,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
- { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25428,52 , 25480,112 , 25592,24 , 25428,52 , 25480,112 , 25592,24 , 14125,28 , 14153,50 , 14203,14 , 14125,28 , 14153,50 , 14203,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 12811,24 , 4,4 , 8,6 , 4168,10 , 1491,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
- { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25616,39 , 25655,194 , 25849,24 , 25616,39 , 25655,194 , 25849,24 , 14217,29 , 14246,65 , 14311,14 , 14217,29 , 14246,65 , 14311,14 , 403,8 , 407,7 , {84,90,83}, 192,3 , 12835,25 , 4,4 , 4,0 , 4267,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
- { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 25873,48 , 25921,81 , 26002,24 , 25873,48 , 25921,81 , 26002,24 , 14325,30 , 14355,47 , 85,14 , 14325,30 , 14355,47 , 85,14 , 411,6 , 414,8 , {77,65,68}, 0,0 , 12860,21 , 0,4 , 4,0 , 4276,8 , 4284,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
- { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26026,48 , 26074,81 , 26155,24 , 26026,48 , 26074,81 , 26155,24 , 14402,30 , 14432,48 , 85,14 , 14402,30 , 14432,48 , 85,14 , 417,6 , 422,8 , {77,65,68}, 0,0 , 12881,21 , 0,4 , 4,0 , 4290,9 , 4299,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
- { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26179,48 , 26227,84 , 26311,24 , 26179,48 , 26227,84 , 26311,24 , 14480,30 , 14510,51 , 14561,14 , 14480,30 , 14510,51 , 14561,14 , 423,7 , 430,9 , {68,90,68}, 207,2 , 12902,21 , 0,4 , 4,0 , 4305,9 , 4314,8 , 2, 1, 6, 4, 5 }, // Kabyle/Latin/Algeria
- { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4322,10 , 1381,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
- { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26535,48 , 26583,254 , 26837,24 , 26535,48 , 26583,254 , 26837,24 , 14691,28 , 14719,82 , 14801,14 , 14691,28 , 14719,82 , 14801,14 , 430,7 , 439,7 , {84,90,83}, 192,3 , 12949,29 , 0,4 , 4,0 , 4332,6 , 4338,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
- { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4348,8 , 1325,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
- { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26948,47 , 26995,92 , 27087,24 , 26948,47 , 26995,92 , 27087,24 , 14919,28 , 14947,44 , 14991,14 , 14919,28 , 14947,44 , 14991,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13005,24 , 4,4 , 8,6 , 4356,9 , 1836,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
- { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27111,48 , 27159,207 , 27366,24 , 27111,48 , 27159,207 , 27366,24 , 15005,28 , 15033,64 , 15097,14 , 15005,28 , 15033,64 , 15097,14 , 442,2 , 455,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4365,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
- { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 27390,36 , 27426,58 , 27484,24 , 27390,36 , 27426,58 , 27484,24 , 15111,28 , 15139,49 , 15188,14 , 15111,28 , 15139,49 , 15188,14 , 444,3 , 457,6 , {85,83,68}, 12,1 , 13029,19 , 4,4 , 8,6 , 4371,3 , 4374,4 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/UnitedStates
- { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 27508,47 , 27555,68 , 27623,24 , 27508,47 , 27555,68 , 27623,24 , 15202,27 , 15229,48 , 15277,14 , 15202,27 , 15229,48 , 15277,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 13048,21 , 14,5 , 4,0 , 4378,14 , 4392,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
- { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 27647,264 , 134,24 , 17628,48 , 27647,264 , 134,24 , 15291,28 , 15319,133 , 14311,14 , 15291,28 , 15319,133 , 14311,14 , 447,4 , 463,5 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 8,6 , 4397,10 , 1325,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
- { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27911,83 , 27994,111 , 28105,24 , 27911,83 , 27994,111 , 28105,24 , 15452,36 , 15488,63 , 15551,14 , 15452,36 , 15488,63 , 15551,14 , 451,3 , 468,3 , {84,90,83}, 192,3 , 13069,29 , 14,5 , 4,0 , 4407,8 , 4415,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
- { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 15565,28 , 15593,66 , 15659,14 , 15565,28 , 15593,66 , 15659,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 13098,26 , 0,4 , 4,0 , 4424,7 , 4431,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
- { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28274,48 , 28322,83 , 28405,24 , 28274,48 , 28322,83 , 28405,24 , 15673,80 , 15673,80 , 85,14 , 15673,80 , 15673,80 , 85,14 , 454,8 , 471,7 , {90,77,87}, 202,2 , 0,7 , 4,4 , 8,6 , 4438,9 , 1485,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
- { 196, 7, 39, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 453,7 , 453,7 , 364,8 , 1416,27 , 37,5 , 8,10 , 28429,48 , 28477,86 , 134,24 , 28429,48 , 28477,86 , 134,24 , 15753,28 , 15781,73 , 15854,14 , 15753,28 , 15781,73 , 15854,14 , 89,2 , 88,2 , {67,86,69}, 0,0 , 13124,25 , 0,4 , 4,0 , 4447,12 , 4459,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/CapeVerde
- { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28563,48 , 28611,86 , 28697,24 , 28563,48 , 28611,86 , 28697,24 , 15868,28 , 15896,51 , 15947,14 , 15868,28 , 15896,51 , 15947,14 , 462,2 , 478,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4469,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
- { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28721,48 , 28769,111 , 28880,24 , 28721,48 , 28769,111 , 28880,24 , 15961,28 , 15989,93 , 16082,14 , 15961,28 , 15989,93 , 16082,14 , 464,4 , 480,4 , {75,69,83}, 2,3 , 13149,26 , 4,4 , 8,6 , 4475,8 , 4483,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
- { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 0,48 , 28904,136 , 134,24 , 0,48 , 28904,136 , 134,24 , 16096,23 , 16119,92 , 16211,14 , 16096,23 , 16119,92 , 16211,14 , 468,7 , 484,5 , {78,65,68}, 12,1 , 13175,22 , 4,4 , 4,0 , 4495,13 , 4508,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
- { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4516,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
- { 201, 7, 82, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 347,8 , 347,8 , 1443,10 , 1453,23 , 37,5 , 8,10 , 29040,59 , 29099,87 , 134,24 , 29186,48 , 29099,87 , 134,24 , 16225,28 , 16253,72 , 3471,14 , 16225,28 , 16253,72 , 3471,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 7151,11 , 25,5 , 4,0 , 4525,6 , 4531,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
- { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {75,69,83}, 2,3 , 13197,25 , 4,4 , 8,6 , 4542,3 , 1006,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
- { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {84,90,83}, 192,3 , 13222,28 , 4,4 , 8,6 , 4542,3 , 4545,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
- { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 16383,35 , 16418,65 , 16483,14 , 16383,35 , 16418,65 , 16483,14 , 484,6 , 495,6 , {85,71,88}, 197,3 , 13098,26 , 25,5 , 4,0 , 4553,7 , 4431,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
- { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29417,48 , 17676,84 , 134,24 , 29417,48 , 17676,84 , 134,24 , 16497,21 , 16518,75 , 85,14 , 16497,21 , 16518,75 , 85,14 , 75,4 , 74,4 , {75,69,83}, 2,3 , 13250,23 , 4,4 , 83,6 , 4560,7 , 1006,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
- { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29465,48 , 17676,84 , 134,24 , 29465,48 , 17676,84 , 134,24 , 16593,28 , 9539,60 , 14905,14 , 16593,28 , 9539,60 , 14905,14 , 490,9 , 501,8 , {84,90,83}, 192,3 , 13273,28 , 25,5 , 4,0 , 4567,6 , 4573,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
- { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {85,71,88}, 197,3 , 13301,28 , 4,4 , 8,6 , 4581,6 , 1381,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
- { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {75,69,83}, 2,3 , 13329,27 , 4,4 , 8,6 , 4581,6 , 4587,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
+ { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {69,85,82}, 19,1 , 81,11 , 4,4 , 4,0 , 77,5 , 99,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo
+ { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 14,6 , 14,6 , 20,9 , 29,8 , 141,10 , 10,17 , 18,7 , 25,12 , 943,46 , 989,61 , 1050,24 , 1074,46 , 1120,62 , 1050,24 , 483,27 , 510,28 , 538,14 , 483,27 , 510,28 , 538,14 , 9,3 , 9,4 , {69,84,66}, 20,2 , 92,34 , 4,4 , 8,6 , 105,4 , 109,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
+ { 8, 1, 64, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,71,80}, 22,5 , 126,70 , 14,5 , 19,6 , 114,7 , 121,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
+ { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,90,68}, 27,5 , 196,91 , 14,5 , 19,6 , 114,7 , 124,7 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/Algeria
+ { 8, 1, 17, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {66,72,68}, 32,5 , 287,91 , 14,5 , 19,6 , 114,7 , 131,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
+ { 8, 1, 42, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {88,65,70}, 37,4 , 378,84 , 14,5 , 19,6 , 114,7 , 138,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
+ { 8, 1, 48, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,77,70}, 41,7 , 462,105 , 14,5 , 19,6 , 114,7 , 142,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
+ { 8, 1, 59, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,74,70}, 5,3 , 567,84 , 14,5 , 19,6 , 114,7 , 151,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
+ { 8, 1, 67, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,82,78}, 8,3 , 651,91 , 14,5 , 19,6 , 114,7 , 157,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
+ { 8, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1492,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,81,68}, 48,5 , 742,84 , 14,5 , 19,6 , 114,7 , 164,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
+ { 8, 1, 105, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 53,1 , 826,133 , 14,5 , 19,6 , 114,7 , 170,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
+ { 8, 1, 109, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {74,79,68}, 54,5 , 959,84 , 14,5 , 19,6 , 114,7 , 177,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
+ { 8, 1, 115, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,87,68}, 59,5 , 1043,84 , 14,5 , 19,6 , 114,7 , 183,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
+ { 8, 1, 119, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,66,80}, 64,5 , 1127,84 , 14,5 , 19,6 , 114,7 , 189,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
+ { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,89,68}, 69,5 , 1211,77 , 14,5 , 19,6 , 114,7 , 194,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
+ { 8, 1, 136, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,82,79}, 74,5 , 1288,112 , 14,5 , 19,6 , 114,7 , 199,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Mauritania
+ { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1584,71 , 1655,71 , 1726,24 , 1655,71 , 1750,71 , 1821,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 79,5 , 1400,77 , 14,5 , 19,6 , 114,7 , 208,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
+ { 8, 1, 162, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {79,77,82}, 84,5 , 1477,77 , 14,5 , 19,6 , 114,7 , 214,5 , 3, 0, 6, 4, 5 }, // Arabic/Arabic/Oman
+ { 8, 1, 165, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 53,1 , 826,133 , 14,5 , 19,6 , 114,7 , 219,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/PalestinianTerritories
+ { 8, 1, 175, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {81,65,82}, 89,5 , 1554,70 , 4,4 , 4,0 , 114,7 , 225,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
+ { 8, 1, 186, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,65,82}, 94,5 , 1624,77 , 4,4 , 4,0 , 114,7 , 228,24 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/SaudiArabia
+ { 8, 1, 194, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,79,83}, 99,1 , 1701,77 , 14,5 , 19,6 , 114,7 , 252,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
+ { 8, 1, 201, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,68,71}, 0,0 , 1778,84 , 14,5 , 19,6 , 114,7 , 259,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
+ { 8, 1, 207, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,89,80}, 100,5 , 1862,77 , 4,4 , 4,0 , 114,7 , 266,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
+ { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {84,78,68}, 105,5 , 1939,77 , 4,4 , 4,0 , 114,7 , 271,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
+ { 8, 1, 223, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {65,69,68}, 110,5 , 2016,91 , 14,5 , 19,6 , 114,7 , 275,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/UnitedArabEmirates
+ { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 79,5 , 1400,77 , 14,5 , 19,6 , 114,7 , 299,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/WesternSahara
+ { 8, 1, 237, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {89,69,82}, 115,5 , 2107,70 , 4,4 , 4,0 , 114,7 , 314,5 , 0, 0, 6, 4, 5 }, // Arabic/Arabic/Yemen
+ { 9, 10, 11, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 58,7 , 58,7 , 187,8 , 195,21 , 61,4 , 65,10 , 1845,48 , 1893,106 , 1999,24 , 1845,48 , 1893,106 , 1999,24 , 618,28 , 646,62 , 708,15 , 618,28 , 646,62 , 708,15 , 13,12 , 14,12 , {65,77,68}, 120,3 , 2177,46 , 25,5 , 4,0 , 319,7 , 326,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
+ { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 216,8 , 224,18 , 75,8 , 83,12 , 2023,62 , 2085,88 , 158,27 , 2023,62 , 2085,88 , 158,27 , 723,37 , 760,58 , 85,14 , 723,37 , 760,58 , 85,14 , 25,9 , 26,7 , {73,78,82}, 123,1 , 0,7 , 14,5 , 4,0 , 334,7 , 341,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
+ { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2173,48 , 2221,77 , 158,27 , 2173,48 , 2221,77 , 158,27 , 818,26 , 844,67 , 99,14 , 818,26 , 844,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 124,4 , 2223,41 , 14,5 , 4,0 , 345,12 , 357,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
+ { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2298,77 , 2298,77 , 158,27 , 2298,77 , 2298,77 , 158,27 , 911,67 , 911,67 , 99,14 , 911,67 , 911,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 128,4 , 2264,12 , 14,5 , 4,0 , 367,10 , 367,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
+ { 14, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 65,9 , 65,9 , 72,10 , 269,18 , 37,5 , 8,10 , 2375,48 , 2423,93 , 2516,24 , 2375,48 , 2423,93 , 2516,24 , 978,21 , 999,68 , 1067,14 , 978,21 , 999,68 , 1081,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2276,12 , 25,5 , 30,7 , 377,7 , 384,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
+ { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {66,68,84}, 132,1 , 2288,21 , 0,4 , 37,6 , 392,5 , 397,8 , 2, 1, 5, 6, 7 }, // Bengali/Bengali/Bangladesh
+ { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {73,78,82}, 123,1 , 2309,19 , 0,4 , 37,6 , 392,5 , 405,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
+ { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 93,9 , 93,9 , 93,9 , 93,9 , 72,10 , 293,30 , 95,22 , 117,27 , 2663,63 , 2726,191 , 2917,27 , 2944,27 , 2971,132 , 3103,27 , 1208,34 , 1242,79 , 1321,27 , 1208,34 , 1242,79 , 1321,27 , 43,5 , 40,6 , {66,84,78}, 133,3 , 2328,15 , 4,4 , 4,0 , 409,6 , 415,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
+ { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 3130,55 , 3185,78 , 158,27 , 3130,55 , 3185,78 , 158,27 , 1348,33 , 1381,43 , 1424,21 , 1348,33 , 1381,43 , 1424,21 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2343,11 , 14,5 , 4,0 , 420,9 , 429,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
+ { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 340,18 , 37,5 , 8,10 , 3263,59 , 3322,82 , 3404,24 , 3263,59 , 3322,82 , 3404,24 , 1445,21 , 1466,55 , 1521,14 , 1445,21 , 1466,55 , 1521,14 , 48,7 , 46,7 , {66,71,78}, 136,3 , 2354,47 , 25,5 , 4,0 , 434,9 , 443,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
+ { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 3428,43 , 3471,88 , 3559,24 , 3428,43 , 3471,88 , 3559,24 , 1535,25 , 1560,54 , 1614,14 , 1535,25 , 1560,54 , 1614,14 , 55,5 , 53,3 , {77,77,75}, 139,1 , 2401,18 , 14,5 , 4,0 , 451,3 , 454,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
+ { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 358,6 , 10,17 , 144,5 , 149,10 , 3583,48 , 3631,99 , 3730,24 , 3754,48 , 3802,95 , 3897,24 , 1628,21 , 1649,56 , 1705,14 , 1628,21 , 1649,56 , 1705,14 , 60,10 , 56,13 , {66,89,82}, 140,2 , 2419,23 , 4,4 , 4,0 , 460,10 , 470,8 , 0, 0, 7, 6, 7 }, // Belarusian/Cyrillic/Belarus
+ { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 109,9 , 364,8 , 10,17 , 18,7 , 25,12 , 3921,71 , 3921,71 , 158,27 , 3921,71 , 3921,71 , 158,27 , 1719,46 , 1719,46 , 1765,14 , 1719,46 , 1719,46 , 1765,14 , 70,5 , 69,5 , {75,72,82}, 142,1 , 2442,18 , 4,4 , 8,6 , 478,5 , 483,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
+ { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 4,4 , 8,6 , 490,6 , 496,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
+ { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 4,4 , 8,6 , 490,6 , 503,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
+ { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 393,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {67,78,89}, 143,1 , 2480,10 , 4,4 , 8,6 , 510,4 , 514,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
+ { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2490,9 , 4,4 , 4,0 , 510,4 , 516,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/HongKong
+ { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2499,10 , 4,4 , 4,0 , 510,4 , 525,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
+ { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 27,8 , 399,13 , 188,7 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {83,71,68}, 12,1 , 2509,11 , 4,4 , 4,0 , 510,4 , 534,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
+ { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2490,9 , 4,4 , 8,6 , 537,4 , 541,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/HongKong
+ { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 412,7 , 419,15 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2520,10 , 4,4 , 4,0 , 537,4 , 555,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
+ { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 179,8 , 399,13 , 172,6 , 208,11 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {84,87,68}, 148,3 , 2530,10 , 4,4 , 4,0 , 537,4 , 569,2 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
+ { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {72,82,75}, 151,2 , 2540,74 , 25,5 , 4,0 , 571,8 , 579,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
+ { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {66,65,77}, 153,2 , 2614,106 , 25,5 , 4,0 , 571,8 , 587,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/BosniaAndHerzegowina
+ { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 187,8 , 462,18 , 61,4 , 219,9 , 4747,48 , 4795,82 , 4877,24 , 4747,48 , 4901,84 , 158,27 , 2146,21 , 2167,49 , 2216,14 , 2146,21 , 2167,49 , 2216,14 , 81,4 , 80,4 , {67,90,75}, 155,2 , 2720,56 , 25,5 , 4,0 , 606,7 , 613,15 , 2, 1, 1, 6, 7 }, // Czech/Latin/CzechRepublic
+ { 29, 7, 58, 44, 46, 44, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 27,8 , 480,23 , 144,5 , 149,10 , 4985,48 , 5033,84 , 134,24 , 5117,59 , 5033,84 , 134,24 , 2230,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 2776,42 , 25,5 , 4,0 , 628,5 , 633,7 , 2, 1, 1, 6, 7 }, // Danish/Latin/Denmark
+ { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 19,6 , 640,10 , 650,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
+ { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,87,71}, 159,4 , 2837,55 , 14,5 , 19,6 , 640,10 , 659,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
+ { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 511,7 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 25,5 , 4,0 , 664,6 , 670,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
+ { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2892,97 , 14,5 , 19,6 , 640,10 , 676,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/CuraSao
+ { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {83,82,68}, 12,1 , 2989,24 , 14,5 , 19,6 , 640,10 , 683,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
+ { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2892,97 , 14,5 , 19,6 , 640,10 , 691,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/SintMaarten
+ { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 703,12 , 715,13 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStates
+ { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 5371,80 , 5451,154 , 5605,36 , 5371,80 , 5451,154 , 5605,36 , 2452,49 , 2501,85 , 2586,21 , 2452,49 , 2501,85 , 2586,21 , 85,4 , 84,4 , {85,83,68}, 12,1 , 0,7 , 14,5 , 4,0 , 728,10 , 738,25 , 2, 1, 7, 6, 7 }, // English/Deseret/UnitedStates
+ { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 770,14 , 2, 1, 7, 6, 7 }, // English/Latin/AmericanSamoa
+ { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 784,19 , 2, 1, 7, 6, 7 }, // English/Latin/AntiguaAndBarbuda
+ { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {65,85,68}, 12,1 , 3119,59 , 4,4 , 4,0 , 803,18 , 821,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
+ { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,83,68}, 12,1 , 3178,53 , 4,4 , 8,6 , 763,7 , 830,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
+ { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,66,68}, 12,1 , 3231,56 , 4,4 , 8,6 , 763,7 , 837,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
+ { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 37,5 , 228,24 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 19,1 , 2818,19 , 25,5 , 4,0 , 763,7 , 845,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
+ { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 524,12 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,90,68}, 12,1 , 3287,47 , 4,4 , 4,0 , 763,7 , 852,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
+ { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,77,68}, 12,1 , 3334,53 , 4,4 , 8,6 , 763,7 , 858,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
+ { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 3387,50 , 4,4 , 4,0 , 763,7 , 865,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
+ { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 3437,50 , 4,4 , 8,6 , 763,7 , 873,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
+ { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 3487,53 , 4,4 , 8,6 , 881,16 , 897,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
+ { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,89,68}, 12,1 , 3540,71 , 4,4 , 8,6 , 763,7 , 903,14 , 2, 1, 1, 6, 7 }, // English/Latin/CaymanIslands
+ { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 917,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
+ { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {70,74,68}, 12,1 , 3611,47 , 4,4 , 8,6 , 763,7 , 925,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
+ { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 929,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
+ { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,77,68}, 172,1 , 3705,50 , 4,4 , 8,6 , 763,7 , 937,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
+ { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 3755,47 , 4,4 , 8,6 , 763,7 , 943,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
+ { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,73,80}, 171,1 , 3802,53 , 4,4 , 4,0 , 763,7 , 948,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
+ { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 957,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
+ { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 964,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
+ { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,89,68}, 12,1 , 3855,56 , 4,4 , 8,6 , 763,7 , 968,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
+ { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {72,75,68}, 12,1 , 3911,56 , 4,4 , 8,6 , 763,7 , 974,19 , 2, 1, 7, 6, 7 }, // English/Latin/HongKong
+ { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {73,78,82}, 123,1 , 3967,44 , 14,5 , 4,0 , 763,7 , 993,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
+ { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 99,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2818,19 , 4,4 , 4,0 , 763,7 , 998,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
+ { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 287,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {74,77,68}, 12,1 , 4011,53 , 4,4 , 4,0 , 763,7 , 1005,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
+ { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,69,83}, 2,3 , 4064,53 , 4,4 , 8,6 , 763,7 , 1012,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
+ { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3119,59 , 4,4 , 8,6 , 763,7 , 1017,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
+ { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4117,61 , 4,4 , 8,6 , 763,7 , 1025,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
+ { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 4178,53 , 4,4 , 8,6 , 763,7 , 1032,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
+ { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 4231,54 , 4,4 , 8,6 , 763,7 , 1039,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
+ { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,87,75}, 178,2 , 4285,53 , 4,4 , 8,6 , 763,7 , 1049,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
+ { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 19,1 , 2818,19 , 4,4 , 4,0 , 763,7 , 1055,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
+ { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1060,16 , 2, 1, 7, 6, 7 }, // English/Latin/MarshallIslands
+ { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 4338,53 , 4,4 , 8,6 , 763,7 , 1076,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
+ { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1085,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
+ { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,65,68}, 12,1 , 4391,53 , 4,4 , 4,0 , 763,7 , 1095,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
+ { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {78,90,68}, 12,1 , 4444,62 , 4,4 , 4,0 , 763,7 , 1102,11 , 2, 1, 7, 6, 7 }, // English/Latin/NewZealand
+ { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 4506,50 , 4,4 , 8,6 , 763,7 , 1113,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
+ { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1120,24 , 2, 1, 1, 6, 7 }, // English/Latin/NorthernMarianaIslands
+ { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {80,75,82}, 180,2 , 4556,53 , 14,5 , 4,0 , 763,7 , 1144,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
+ { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1152,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
+ { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,71,75}, 139,1 , 4609,73 , 4,4 , 8,6 , 763,7 , 1157,16 , 2, 1, 1, 6, 7 }, // English/Latin/PapuaNewGuinea
+ { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 4682,42 , 4,4 , 8,6 , 763,7 , 1173,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
+ { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1184,11 , 2, 1, 7, 6, 7 }, // English/Latin/PuertoRico
+ { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1195,21 , 2, 1, 1, 6, 7 }, // English/Latin/SaintKittsAndNevis
+ { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1216,11 , 2, 1, 1, 6, 7 }, // English/Latin/SaintLucia
+ { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1227,32 , 2, 1, 1, 6, 7 }, // English/Latin/SaintVincentAndTheGrenadines
+ { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {87,83,84}, 184,3 , 4724,40 , 4,4 , 8,6 , 763,7 , 1259,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
+ { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 4764,59 , 4,4 , 8,6 , 763,7 , 1264,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
+ { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,76,76}, 189,2 , 4823,68 , 4,4 , 8,6 , 763,7 , 1274,12 , 0, 0, 1, 6, 7 }, // English/Latin/SierraLeone
+ { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {83,71,68}, 12,1 , 4891,56 , 4,4 , 8,6 , 763,7 , 1286,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
+ { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,66,68}, 12,1 , 4947,74 , 4,4 , 8,6 , 763,7 , 1295,15 , 2, 1, 1, 6, 7 }, // English/Latin/SolomonIslands
+ { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 536,10 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4117,61 , 4,4 , 8,6 , 763,7 , 1310,12 , 2, 1, 7, 6, 7 }, // English/Latin/SouthAfrica
+ { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 5021,53 , 4,4 , 8,6 , 763,7 , 1322,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
+ { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,90,83}, 192,3 , 5074,62 , 4,4 , 8,6 , 763,7 , 1331,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
+ { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 5136,49 , 4,4 , 8,6 , 763,7 , 1339,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
+ { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,84,68}, 12,1 , 5185,86 , 4,4 , 4,0 , 763,7 , 1344,19 , 2, 1, 7, 6, 7 }, // English/Latin/TrinidadAndTobago
+ { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1363,24 , 2, 1, 1, 6, 7 }, // English/Latin/TurksAndCaicosIslands
+ { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 5271,56 , 4,4 , 8,6 , 763,7 , 1387,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
+ { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 1393,15 , 1408,14 , 2, 1, 1, 6, 7 }, // English/Latin/UnitedKingdom
+ { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1422,21 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesMinorOutlyingIslands
+ { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 5327,44 , 4,4 , 8,6 , 763,7 , 1443,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
+ { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1450,22 , 2, 1, 1, 6, 7 }, // English/Latin/BritishVirginIslands
+ { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1472,19 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesVirginIslands
+ { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,77,87}, 202,2 , 5371,50 , 4,4 , 8,6 , 763,7 , 1491,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
+ { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 364,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 3013,35 , 4,4 , 4,0 , 763,7 , 1497,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
+ { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 1505,11 , 2, 1, 1, 6, 7 }, // English/Latin/IsleOfMan
+ { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 1516,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
+ { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,83,80}, 171,1 , 5421,68 , 4,4 , 8,6 , 763,7 , 1522,11 , 2, 1, 1, 6, 7 }, // English/Latin/SouthSudan
+ { 33, 7, 68, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 169,8 , 169,8 , 187,8 , 462,18 , 61,4 , 252,9 , 5641,59 , 5700,91 , 5791,24 , 5641,59 , 5700,91 , 5791,24 , 2607,14 , 2621,63 , 2607,14 , 2607,14 , 2621,63 , 2607,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 5489,20 , 25,5 , 30,7 , 1533,5 , 1538,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
+ { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 503,8 , 82,17 , 37,5 , 8,10 , 5815,48 , 5863,83 , 134,24 , 5815,48 , 5863,83 , 134,24 , 2684,28 , 2712,74 , 2786,14 , 2684,28 , 2712,74 , 2786,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 5509,42 , 4,4 , 43,5 , 1543,8 , 1551,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/FaroeIslands
+ { 36, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 546,8 , 554,17 , 159,4 , 163,9 , 5946,69 , 6015,105 , 6120,24 , 6144,129 , 6144,129 , 6120,24 , 2800,21 , 2821,67 , 2888,14 , 2800,21 , 2902,81 , 2888,14 , 91,3 , 90,3 , {69,85,82}, 19,1 , 5551,20 , 25,5 , 4,0 , 1558,5 , 1563,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
+ { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1576,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
+ { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,90,68}, 207,2 , 5571,51 , 25,5 , 30,7 , 1568,8 , 1582,7 , 2, 1, 6, 4, 5 }, // French/Latin/Algeria
+ { 37, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 511,7 , 99,16 , 37,5 , 261,23 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1589,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
+ { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1597,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
+ { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1602,12 , 0, 0, 1, 6, 7 }, // French/Latin/BurkinaFaso
+ { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {66,73,70}, 212,3 , 5681,53 , 25,5 , 30,7 , 1568,8 , 1614,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
+ { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1621,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
+ { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 115,8 , 99,16 , 37,5 , 228,24 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 5790,54 , 25,5 , 30,7 , 1629,17 , 897,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
+ { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1646,25 , 0, 0, 1, 6, 7 }, // French/Latin/CentralAfricanRepublic
+ { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1671,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
+ { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {75,77,70}, 215,2 , 5844,51 , 25,5 , 30,7 , 1568,8 , 1676,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
+ { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,68,70}, 217,2 , 5895,53 , 25,5 , 30,7 , 1568,8 , 1683,32 , 2, 1, 1, 6, 7 }, // French/Latin/CongoKinshasa
+ { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1715,17 , 0, 0, 1, 6, 7 }, // French/Latin/CongoBrazzaville
+ { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1732,13 , 0, 0, 1, 6, 7 }, // French/Latin/IvoryCoast
+ { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,74,70}, 5,3 , 5948,57 , 25,5 , 30,7 , 1568,8 , 1745,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
+ { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1753,18 , 0, 0, 1, 6, 7 }, // French/Latin/EquatorialGuinea
+ { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1771,16 , 2, 1, 1, 6, 7 }, // French/Latin/FrenchGuiana
+ { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 6005,35 , 25,5 , 30,7 , 1568,8 , 1787,19 , 0, 0, 1, 6, 7 }, // French/Latin/FrenchPolynesia
+ { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1806,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
+ { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1811,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
+ { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {71,78,70}, 223,2 , 6040,48 , 25,5 , 30,7 , 1568,8 , 1821,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
+ { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {72,84,71}, 225,1 , 6088,57 , 25,5 , 30,7 , 1568,8 , 1827,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
+ { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1832,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
+ { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 6145,54 , 25,5 , 30,7 , 1568,8 , 1039,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
+ { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1842,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
+ { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1846,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
+ { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,82,79}, 226,2 , 6199,66 , 25,5 , 30,7 , 1568,8 , 1856,10 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritania
+ { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 6265,63 , 25,5 , 30,7 , 1568,8 , 1866,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
+ { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1873,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
+ { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1880,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
+ { 37, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,65,68}, 0,0 , 6328,54 , 25,5 , 30,7 , 1568,8 , 1886,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
+ { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 6005,35 , 25,5 , 30,7 , 1568,8 , 1891,18 , 0, 0, 1, 6, 7 }, // French/Latin/NewCaledonia
+ { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1909,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
+ { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1914,7 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
+ { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 6382,50 , 25,5 , 30,7 , 1568,8 , 1921,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
+ { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1927,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
+ { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 6432,71 , 25,5 , 30,7 , 1568,8 , 1264,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
+ { 37, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 187,8 , 10,17 , 37,5 , 284,14 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 6503,45 , 14,5 , 48,5 , 1934,15 , 1949,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
+ { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,89,80}, 233,2 , 6548,51 , 25,5 , 30,7 , 1568,8 , 1955,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
+ { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1960,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
+ { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {84,78,68}, 235,2 , 6599,51 , 25,5 , 30,7 , 1568,8 , 1964,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
+ { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 6650,51 , 25,5 , 30,7 , 1568,8 , 1443,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
+ { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1971,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
+ { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1987,31 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
+ { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 185,11 , 196,10 , 141,10 , 10,17 , 37,5 , 8,10 , 6421,61 , 6482,142 , 6624,36 , 6421,61 , 6482,142 , 6624,36 , 3084,28 , 3112,69 , 3181,14 , 3084,28 , 3112,69 , 3181,14 , 0,2 , 0,2 , {71,66,80}, 171,1 , 6701,22 , 4,4 , 8,6 , 2018,8 , 2026,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/UnitedKingdom
+ { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 82,17 , 37,5 , 8,10 , 6660,48 , 6708,87 , 6795,24 , 6660,48 , 6708,87 , 6795,24 , 3195,28 , 3223,49 , 3272,14 , 3195,28 , 3223,49 , 3272,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 6723,20 , 4,4 , 8,6 , 2048,6 , 2054,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
+ { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 213,8 , 213,8 , 187,8 , 571,19 , 37,5 , 8,10 , 6819,48 , 6867,99 , 6966,24 , 6819,48 , 6867,99 , 6966,24 , 3286,28 , 3314,62 , 3376,14 , 3286,28 , 3314,62 , 3376,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 6743,19 , 25,5 , 4,0 , 2060,7 , 2067,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
+ { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2084,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
+ { 42, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 590,19 , 37,5 , 8,10 , 7180,48 , 7038,83 , 134,24 , 7228,58 , 7286,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 14,5 , 4,0 , 2095,24 , 2119,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
+ { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2129,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
+ { 42, 7, 123, 46, 39, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 0,0 , 6781,58 , 14,5 , 4,0 , 2077,7 , 2136,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
+ { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2149,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
+ { 42, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 230,3 , 6781,58 , 14,5 , 48,5 , 2158,21 , 2179,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
+ { 43, 16, 85, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 19,1 , 6839,19 , 25,5 , 4,0 , 2186,8 , 2194,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
+ { 43, 16, 56, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 19,1 , 6839,19 , 4,4 , 4,0 , 2186,8 , 2200,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
+ { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 239,11 , 239,11 , 72,10 , 82,17 , 18,7 , 25,12 , 4985,48 , 7723,96 , 134,24 , 4985,48 , 7723,96 , 134,24 , 3610,28 , 3638,98 , 3736,14 , 3610,28 , 3638,98 , 3736,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 6858,59 , 4,4 , 43,5 , 2206,11 , 2217,16 , 2, 1, 1, 6, 7 }, // Greenlandic/Latin/Greenland
+ { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 250,9 , 250,9 , 609,7 , 224,18 , 298,8 , 306,13 , 7819,64 , 7883,87 , 7970,31 , 8001,67 , 8068,87 , 7970,31 , 3750,32 , 3782,53 , 3835,19 , 3750,32 , 3782,53 , 3835,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 6917,20 , 4,4 , 8,6 , 2233,7 , 2240,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
+ { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 6937,12 , 14,5 , 4,0 , 2244,5 , 2249,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
+ { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 0,7 , 14,5 , 4,0 , 2244,5 , 2257,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
+ { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 6949,36 , 14,5 , 4,0 , 2244,5 , 2261,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
+ { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 34, 34, 39, 39, 0,6 , 0,6 , 259,6 , 259,6 , 27,8 , 616,18 , 37,5 , 8,10 , 8312,58 , 8370,72 , 158,27 , 8442,48 , 8370,72 , 158,27 , 3941,46 , 3987,65 , 4052,19 , 3941,46 , 3987,65 , 4071,21 , 103,6 , 103,5 , {73,76,83}, 53,1 , 6985,54 , 25,5 , 4,0 , 2266,5 , 2271,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
+ { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 265,9 , 274,8 , 634,6 , 10,17 , 18,7 , 25,12 , 8490,75 , 8490,75 , 8565,30 , 8490,75 , 8490,75 , 8565,30 , 4092,38 , 4130,57 , 4187,19 , 4092,38 , 4130,57 , 4187,19 , 109,9 , 108,7 , {73,78,82}, 123,1 , 7039,19 , 14,5 , 4,0 , 2276,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
+ { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 282,8 , 282,8 , 640,11 , 651,19 , 61,4 , 219,9 , 8595,64 , 8659,98 , 8757,25 , 8595,64 , 8659,98 , 8782,25 , 4206,19 , 4225,52 , 4277,17 , 4206,19 , 4225,52 , 4277,17 , 118,3 , 115,3 , {72,85,70}, 237,2 , 7058,20 , 25,5 , 4,0 , 2286,6 , 2292,12 , 0, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
+ { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 142,8 , 142,8 , 546,8 , 462,18 , 37,5 , 8,10 , 8807,48 , 8855,82 , 8937,24 , 8807,48 , 8855,82 , 8961,24 , 4294,28 , 4322,81 , 4403,14 , 4294,28 , 4322,81 , 4417,14 , 121,4 , 118,4 , {73,83,75}, 157,2 , 7078,49 , 4,4 , 8,6 , 2304,8 , 2312,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
+ { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 27,8 , 123,18 , 144,5 , 149,10 , 8985,48 , 9033,87 , 134,24 , 8985,48 , 9033,87 , 134,24 , 4431,28 , 4459,43 , 4502,14 , 4431,28 , 4459,43 , 4502,14 , 0,2 , 0,2 , {73,68,82}, 239,2 , 7127,23 , 4,4 , 4,0 , 2318,16 , 2334,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
+ { 53, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 9120,48 , 9168,93 , 158,27 , 9120,48 , 9168,93 , 158,27 , 4516,28 , 4544,57 , 85,14 , 4516,28 , 4544,57 , 85,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 7150,12 , 14,5 , 4,0 , 2343,11 , 2354,7 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France
+ { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 9261,62 , 9323,107 , 9430,24 , 9261,62 , 9323,107 , 9430,24 , 4601,37 , 4638,75 , 4713,14 , 4601,37 , 4638,75 , 4713,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 81,11 , 4,4 , 4,0 , 2361,7 , 2368,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
+ { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 4,0 , 2372,8 , 2380,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
+ { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 4,0 , 2372,8 , 2386,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/SanMarino
+ { 58, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 309,8 , 206,7 , 187,8 , 10,17 , 37,5 , 284,14 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 7162,53 , 14,5 , 48,5 , 2372,8 , 2396,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
+ { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 125,5 , 125,5 , 536,10 , 399,13 , 61,4 , 319,10 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 4883,14 , 4897,28 , 4883,14 , 4883,14 , 4897,28 , 4883,14 , 125,2 , 122,2 , {74,80,89}, 143,1 , 7215,10 , 4,4 , 4,0 , 2404,3 , 2407,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
+ { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 3208, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 317,12 , 329,11 , 634,6 , 99,16 , 298,8 , 306,13 , 9714,91 , 9805,86 , 9891,31 , 9714,91 , 9805,86 , 9922,31 , 4925,28 , 4953,53 , 5006,19 , 4925,28 , 4953,53 , 5006,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7225,20 , 4,4 , 8,6 , 2409,5 , 2414,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
+ { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 9953,72 , 9953,72 , 10025,24 , 9953,72 , 9953,72 , 10025,24 , 5025,54 , 5079,56 , 5135,14 , 5025,54 , 5079,56 , 5135,14 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7245,23 , 14,5 , 4,0 , 2418,5 , 2423,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
+ { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10049,61 , 10110,83 , 158,27 , 10049,61 , 10110,83 , 158,27 , 5149,28 , 5177,54 , 85,14 , 5149,28 , 5177,54 , 85,14 , 0,2 , 0,2 , {75,90,84}, 241,1 , 7268,24 , 25,5 , 4,0 , 2433,10 , 2443,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
+ { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 10193,60 , 10253,101 , 158,27 , 10193,60 , 10253,101 , 158,27 , 5231,35 , 5266,84 , 85,14 , 5231,35 , 5266,84 , 85,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 0,7 , 14,5 , 4,0 , 2452,11 , 1921,6 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
+ { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10354,60 , 10414,80 , 158,27 , 10494,59 , 10553,80 , 158,27 , 5350,28 , 5378,57 , 85,14 , 5435,28 , 5463,57 , 85,14 , 0,2 , 0,2 , {75,71,83}, 242,3 , 0,7 , 14,5 , 4,0 , 2463,6 , 2469,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
+ { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,82,87}, 245,1 , 7292,13 , 4,4 , 8,6 , 2479,3 , 2482,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/SouthKorea
+ { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,80,87}, 0,0 , 7305,23 , 4,4 , 8,6 , 2479,3 , 2486,14 , 0, 0, 1, 6, 7 }, // Korean/Korean/NorthKorea
+ { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 10672,60 , 10732,106 , 158,27 , 10672,60 , 10732,106 , 158,27 , 5562,34 , 5596,89 , 85,14 , 5562,34 , 5596,89 , 85,14 , 129,5 , 126,5 , {66,73,70}, 212,3 , 7328,27 , 0,4 , 4,0 , 2500,8 , 2508,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
+ { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 717,18 , 61,4 , 349,24 , 10838,62 , 10900,75 , 158,27 , 10975,61 , 10900,75 , 158,27 , 5685,23 , 5708,57 , 5765,18 , 5783,24 , 5708,57 , 1765,14 , 134,8 , 131,8 , {76,65,75}, 246,1 , 7355,14 , 4,4 , 48,5 , 2516,3 , 2519,9 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
+ { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 347,8 , 347,8 , 187,8 , 735,26 , 37,5 , 8,10 , 11036,65 , 11101,101 , 134,24 , 11202,65 , 11267,101 , 134,24 , 5807,21 , 5828,72 , 5900,14 , 5807,21 , 5914,72 , 5900,14 , 142,14 , 139,11 , {76,86,76}, 247,2 , 7369,59 , 4,4 , 8,6 , 2528,8 , 2536,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
+ { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {67,68,70}, 217,2 , 7428,23 , 25,5 , 4,0 , 2543,7 , 2550,29 , 2, 1, 1, 6, 7 }, // Lingala/Latin/CongoKinshasa
+ { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {65,79,65}, 249,2 , 7451,23 , 25,5 , 4,0 , 2543,7 , 2579,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
+ { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 37,4 , 7474,23 , 25,5 , 4,0 , 2543,7 , 2585,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CentralAfricanRepublic
+ { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 37,4 , 7474,23 , 25,5 , 4,0 , 2543,7 , 2611,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CongoBrazzaville
+ { 73, 7, 124, 44, 160, 59, 37, 48, 8211, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 364,8 , 364,8 , 72,10 , 761,27 , 37,5 , 8,10 , 11643,70 , 11713,96 , 11809,24 , 11643,70 , 11713,96 , 11809,24 , 6128,21 , 6149,89 , 6238,14 , 6128,21 , 6149,89 , 6238,14 , 164,9 , 156,6 , {76,84,76}, 251,2 , 7497,62 , 25,5 , 4,0 , 2616,8 , 2624,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
+ { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 788,7 , 123,18 , 37,5 , 8,10 , 11833,63 , 11896,85 , 11981,24 , 11833,63 , 11896,85 , 11981,24 , 6252,34 , 6286,54 , 1521,14 , 6252,34 , 6286,54 , 1521,14 , 173,10 , 162,8 , {77,75,68}, 253,3 , 7559,23 , 14,5 , 4,0 , 2631,10 , 2641,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
+ { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 12005,48 , 12053,92 , 134,24 , 12005,48 , 12053,92 , 134,24 , 6340,34 , 6374,60 , 6434,14 , 6340,34 , 6374,60 , 6434,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 7582,13 , 4,4 , 4,0 , 2651,8 , 2659,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
+ { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {77,89,82}, 256,2 , 7595,23 , 4,4 , 8,6 , 2671,13 , 2684,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
+ { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 524,12 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {66,78,68}, 12,1 , 7618,19 , 14,5 , 4,0 , 2671,13 , 2692,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
+ { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {83,71,68}, 12,1 , 7637,22 , 4,4 , 8,6 , 2671,13 , 2698,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
+ { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 372,13 , 385,12 , 27,8 , 795,18 , 18,7 , 25,12 , 12300,62 , 12362,87 , 12449,31 , 12300,62 , 12362,87 , 12449,31 , 6533,41 , 6574,70 , 6644,22 , 6533,41 , 6574,70 , 6644,22 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7659,40 , 0,4 , 4,0 , 2707,6 , 2713,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
+ { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 397,8 , 405,7 , 141,10 , 813,23 , 37,5 , 8,10 , 12480,48 , 12528,86 , 12614,24 , 12480,48 , 12528,86 , 12614,24 , 6666,28 , 6694,63 , 6757,14 , 6666,28 , 6694,63 , 6757,14 , 185,2 , 173,2 , {69,85,82}, 19,1 , 7699,11 , 4,4 , 4,0 , 2719,5 , 1055,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
+ { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 412,9 , 412,9 , 634,6 , 99,16 , 373,7 , 380,12 , 12638,66 , 12704,86 , 12790,32 , 12638,66 , 12704,86 , 12790,32 , 6771,32 , 6803,53 , 4187,19 , 6771,32 , 6803,53 , 4187,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7710,19 , 4,4 , 8,6 , 2724,5 , 2282,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
+ { 82, 2, 143, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 836,31 , 37,5 , 8,10 , 12822,48 , 12870,66 , 158,27 , 12822,48 , 12870,66 , 158,27 , 6856,21 , 6877,43 , 1765,14 , 6856,21 , 6877,43 , 1765,14 , 187,2 , 175,2 , {77,78,84}, 258,1 , 7729,25 , 14,5 , 4,0 , 2729,6 , 2735,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
+ { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 12992,85 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 6953,54 , 7007,14 , 189,14 , 177,14 , {78,80,82}, 259,4 , 7754,52 , 14,5 , 4,0 , 2741,6 , 2747,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
+ { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 13104,80 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 7021,54 , 7007,14 , 109,9 , 108,7 , {73,78,82}, 123,1 , 7806,49 , 14,5 , 4,0 , 2741,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
+ { 85, 7, 161, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 7075,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 7855,44 , 14,5 , 4,0 , 2752,12 , 2764,5 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/Norway
+ { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 10,17 , 18,7 , 25,12 , 13326,89 , 13326,89 , 13415,32 , 13326,89 , 13326,89 , 13415,32 , 7103,33 , 7136,54 , 7190,18 , 7103,33 , 7136,54 , 7190,18 , 89,2 , 88,2 , {73,78,82}, 123,1 , 7899,11 , 14,5 , 4,0 , 2769,5 , 2774,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
+ { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 867,20 , 61,4 , 408,11 , 13447,68 , 13447,68 , 158,27 , 13447,68 , 13447,68 , 158,27 , 7208,49 , 7208,49 , 85,14 , 7208,49 , 7208,49 , 85,14 , 203,4 , 191,4 , {65,70,78}, 263,1 , 7910,13 , 25,5 , 4,0 , 2778,4 , 2782,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
+ { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13585,24 , 13609,74 , 13609,74 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {73,82,82}, 264,1 , 7923,17 , 53,5 , 58,7 , 2791,5 , 2796,5 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Iran
+ { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13683,24 , 13707,64 , 13771,68 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {65,70,78}, 263,1 , 7940,23 , 53,5 , 58,7 , 2801,3 , 2782,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
+ { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 887,10 , 10,17 , 37,5 , 8,10 , 13839,48 , 13887,97 , 13984,24 , 13839,48 , 14008,99 , 13984,24 , 7271,34 , 7305,59 , 7364,14 , 7271,34 , 7305,59 , 7364,14 , 0,2 , 0,2 , {80,76,78}, 265,2 , 7963,77 , 25,5 , 30,7 , 2804,6 , 2810,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
+ { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14107,48 , 14155,89 , 134,24 , 14107,48 , 14155,89 , 134,24 , 7378,28 , 7406,79 , 7485,14 , 7378,28 , 7406,79 , 7485,14 , 0,2 , 0,2 , {66,82,76}, 267,2 , 8040,54 , 4,4 , 8,6 , 2816,19 , 2835,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
+ { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {65,79,65}, 249,2 , 8094,54 , 25,5 , 4,0 , 2841,9 , 2850,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
+ { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {67,86,69}, 0,0 , 8148,69 , 25,5 , 4,0 , 2841,9 , 2856,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/CapeVerde
+ { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 8217,81 , 25,5 , 4,0 , 2841,9 , 2866,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/EastTimor
+ { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 8298,62 , 25,5 , 4,0 , 2841,9 , 2877,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/GuineaBissau
+ { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,79,80}, 144,4 , 8360,53 , 25,5 , 4,0 , 2841,9 , 2889,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
+ { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 8413,72 , 25,5 , 4,0 , 2841,9 , 2908,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
+ { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 8485,20 , 25,5 , 4,0 , 2918,17 , 2935,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
+ { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {83,84,68}, 272,2 , 8505,92 , 25,5 , 4,0 , 2841,9 , 2943,19 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/SaoTomeAndPrincipe
+ { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 39, 39, 34, 34, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14381,68 , 14381,68 , 14449,27 , 14381,68 , 14381,68 , 14449,27 , 7578,38 , 7616,55 , 7671,23 , 7578,38 , 7616,55 , 7671,23 , 216,11 , 203,11 , {73,78,82}, 123,1 , 8597,12 , 14,5 , 4,0 , 2962,6 , 2968,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
+ { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14476,67 , 14476,67 , 158,27 , 14476,67 , 14476,67 , 158,27 , 7694,37 , 7694,37 , 85,14 , 7694,37 , 7694,37 , 85,14 , 0,2 , 0,2 , {80,75,82}, 274,1 , 8609,13 , 14,5 , 4,0 , 2972,5 , 2977,6 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
+ { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 503,8 , 924,28 , 37,5 , 8,10 , 14543,67 , 14610,92 , 14702,24 , 14543,67 , 14610,92 , 14702,24 , 7731,23 , 7754,56 , 7810,14 , 7731,23 , 7754,56 , 7810,14 , 89,2 , 214,2 , {67,72,70}, 230,3 , 8622,20 , 25,5 , 4,0 , 2983,9 , 2992,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
+ { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {82,79,78}, 0,0 , 8642,57 , 25,5 , 4,0 , 2998,6 , 3004,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
+ { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {77,68,76}, 0,0 , 8699,69 , 25,5 , 4,0 , 2998,6 , 3011,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
+ { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {82,85,66}, 275,4 , 8768,89 , 25,5 , 4,0 , 3028,7 , 3035,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
+ { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {66,89,82}, 140,2 , 8857,94 , 25,5 , 4,0 , 3028,7 , 470,8 , 0, 0, 7, 6, 7 }, // Russian/Cyrillic/Belarus
+ { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,90,84}, 241,1 , 8951,83 , 25,5 , 4,0 , 3028,7 , 3041,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
+ { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,71,83}, 242,3 , 9034,81 , 25,5 , 4,0 , 3028,7 , 3050,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
+ { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {77,68,76}, 0,0 , 9115,79 , 25,5 , 4,0 , 3028,7 , 3058,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
+ { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 37,5 , 8,10 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {85,65,72}, 279,1 , 9194,92 , 25,5 , 4,0 , 3028,7 , 3065,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
+ { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 15139,48 , 15187,91 , 15278,24 , 15139,48 , 15187,91 , 15278,24 , 8073,28 , 8101,66 , 8167,14 , 8073,28 , 8101,66 , 8167,14 , 237,2 , 229,2 , {88,65,70}, 37,4 , 9286,25 , 4,4 , 48,5 , 3072,5 , 3077,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/CentralAfricanRepublic
+ { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {82,83,68}, 280,4 , 9311,72 , 25,5 , 4,0 , 3099,6 , 3105,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
+ { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 9383,196 , 25,5 , 4,0 , 3111,6 , 587,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/BosniaAndHerzegowina
+ { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 19,1 , 9579,27 , 25,5 , 4,0 , 3111,6 , 3117,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
+ { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {82,83,68}, 284,4 , 9606,72 , 25,5 , 4,0 , 3111,6 , 3126,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
+ { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 115,8 , 981,20 , 37,5 , 419,40 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15584,83 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8357,28 , 8385,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 288,2 , 9678,196 , 25,5 , 4,0 , 3132,6 , 3138,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/BosniaAndHerzegowina
+ { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 19,1 , 9874,27 , 25,5 , 4,0 , 3099,6 , 3157,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
+ { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 19,1 , 9874,27 , 25,5 , 4,0 , 3099,6 , 3166,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
+ { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 19,1 , 9579,27 , 25,5 , 4,0 , 3111,6 , 3172,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo
+ { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 9901,17 , 14,5 , 4,0 , 3178,4 , 3182,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
+ { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 9918,17 , 14,5 , 4,0 , 3178,4 , 3193,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
+ { 102, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3199,7 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/SouthAfrica
+ { 102, 7, 120, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3199,7 , 0,0 , 2, 1, 1, 6, 7 }, // Southern Sotho/Latin/Lesotho
+ { 103, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3206,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/SouthAfrica
+ { 103, 7, 28, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 0,7 , 4,4 , 4,0 , 3206,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/Botswana
+ { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 16212,47 , 16259,100 , 16359,24 , 16212,47 , 16259,100 , 16359,24 , 8810,32 , 8842,55 , 8897,14 , 8810,32 , 8842,55 , 8897,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 9935,22 , 4,4 , 8,6 , 3214,8 , 1497,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
+ { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 536,10 , 323,17 , 459,7 , 466,13 , 16383,59 , 16442,96 , 16538,32 , 16570,61 , 16442,96 , 16538,32 , 8911,30 , 8941,62 , 9003,19 , 8911,30 , 8941,62 , 9003,19 , 257,5 , 245,4 , {76,75,82}, 290,3 , 9957,19 , 14,5 , 4,0 , 3222,5 , 3227,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/SriLanka
+ { 107, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3238,7 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/SouthAfrica
+ { 107, 7, 204, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 0,7 , 4,4 , 4,0 , 3238,7 , 0,0 , 2, 1, 1, 6, 7 }, // Swati/Latin/Swaziland
+ { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 546,8 , 462,18 , 61,4 , 219,9 , 16793,48 , 16841,82 , 15560,24 , 16793,48 , 16923,89 , 15560,24 , 9117,21 , 9138,52 , 9190,14 , 9117,21 , 9138,52 , 9190,14 , 262,10 , 249,9 , {69,85,82}, 19,1 , 9976,28 , 25,5 , 4,0 , 3245,10 , 3255,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
+ { 109, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 445,8 , 445,8 , 1024,9 , 590,19 , 37,5 , 8,10 , 15431,48 , 17012,86 , 15560,24 , 17098,59 , 17012,86 , 15560,24 , 9204,28 , 9232,52 , 9284,14 , 9298,35 , 9232,52 , 9284,14 , 81,4 , 258,4 , {69,85,82}, 19,1 , 10004,28 , 4,4 , 8,6 , 3264,11 , 3275,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
+ { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {83,79,83}, 99,1 , 10032,22 , 4,4 , 4,0 , 3284,8 , 3292,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
+ { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {68,74,70}, 5,3 , 10054,21 , 4,4 , 4,0 , 3284,8 , 3302,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
+ { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {69,84,66}, 0,2 , 10075,22 , 4,4 , 4,0 , 3284,8 , 3309,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
+ { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3284,8 , 3317,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
+ { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3324,17 , 2054,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
+ { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 479,14 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {65,82,83}, 12,1 , 10097,51 , 4,4 , 4,0 , 3341,7 , 3348,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
+ { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {66,79,66}, 293,2 , 10148,35 , 4,4 , 4,0 , 3341,7 , 3357,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
+ { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 503,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,76,80}, 12,1 , 10183,45 , 4,4 , 48,5 , 3341,7 , 3364,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
+ { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,79,80}, 12,1 , 10228,54 , 4,4 , 4,0 , 3341,7 , 3369,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
+ { 111, 7, 52, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,82,67}, 295,1 , 10282,67 , 4,4 , 4,0 , 3341,7 , 3377,10 , 0, 0, 1, 6, 7 }, // Spanish/Latin/CostaRica
+ { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,85,80}, 12,1 , 10349,42 , 4,4 , 4,0 , 3341,7 , 3387,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
+ { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {68,79,80}, 12,1 , 10391,54 , 4,4 , 4,0 , 3341,7 , 3391,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/DominicanRepublic
+ { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 48,5 , 3341,7 , 3411,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
+ { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 204,3 , 10445,70 , 4,4 , 4,0 , 3341,7 , 3418,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/ElSalvador
+ { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {88,65,70}, 37,4 , 10515,53 , 4,4 , 4,0 , 3341,7 , 3429,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/EquatorialGuinea
+ { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {71,84,81}, 296,1 , 10568,70 , 4,4 , 4,0 , 3341,7 , 3446,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
+ { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 1033,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {72,78,76}, 297,1 , 10638,60 , 4,4 , 4,0 , 3341,7 , 3455,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
+ { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {77,88,78}, 12,1 , 10698,48 , 4,4 , 4,0 , 3341,7 , 3463,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
+ { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {78,73,79}, 298,2 , 10746,69 , 4,4 , 4,0 , 3341,7 , 3469,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
+ { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,65,66}, 300,3 , 10815,54 , 4,4 , 4,0 , 3341,7 , 3478,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
+ { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,89,71}, 303,1 , 10869,61 , 14,5 , 65,6 , 3341,7 , 3484,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
+ { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 493,15 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,69,78}, 304,3 , 10930,62 , 4,4 , 4,0 , 3341,7 , 3492,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
+ { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {80,72,80}, 183,1 , 10992,48 , 25,5 , 4,0 , 3341,7 , 3496,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
+ { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3341,7 , 1184,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/PuertoRico
+ { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 518,6 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3341,7 , 3505,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/UnitedStates
+ { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,89,85}, 12,1 , 11040,48 , 14,5 , 71,7 , 3341,7 , 3519,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
+ { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {86,69,70}, 307,3 , 11088,64 , 4,4 , 48,5 , 3341,7 , 3526,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela
+ { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3341,7 , 3535,14 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CanaryIslands
+ { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {0,0,0}, 0,0 , 11152,0 , 4,4 , 4,0 , 3549,23 , 3572,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/LatinAmericaAndTheCaribbean
+ { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3341,7 , 3585,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CeutaAndMelilla
+ { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {84,90,83}, 192,3 , 11152,27 , 4,4 , 8,6 , 3600,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
+ { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {75,69,83}, 2,3 , 11179,24 , 4,4 , 4,0 , 3600,9 , 1012,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
+ { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {85,71,88}, 197,3 , 11203,25 , 4,4 , 8,6 , 3600,9 , 1387,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
+ { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {83,69,75}, 157,2 , 11228,45 , 25,5 , 4,0 , 3609,7 , 3616,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Sweden
+ { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 19,1 , 11273,19 , 25,5 , 4,0 , 3609,7 , 3623,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
+ { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 19,1 , 11273,19 , 25,5 , 4,0 , 3609,7 , 3630,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/AlandIslands
+ { 116, 2, 209, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 171, 8222, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 158,27 , 17980,48 , 18028,71 , 158,27 , 9770,28 , 9798,55 , 85,14 , 9770,28 , 9798,55 , 85,14 , 0,2 , 0,2 , {84,74,83}, 242,3 , 11292,13 , 14,5 , 4,0 , 3635,6 , 3641,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
+ { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {73,78,82}, 123,1 , 11305,13 , 14,5 , 4,0 , 3651,5 , 3656,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
+ { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {77,89,82}, 256,2 , 11318,22 , 14,5 , 4,0 , 3651,5 , 3663,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
+ { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {83,71,68}, 12,1 , 11340,24 , 14,5 , 4,0 , 3651,5 , 3670,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
+ { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {76,75,82}, 310,3 , 11364,20 , 14,5 , 4,0 , 3651,5 , 3681,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/SriLanka
+ { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 499,11 , 499,11 , 503,8 , 99,16 , 18,7 , 25,12 , 18360,66 , 18426,86 , 18512,31 , 18543,78 , 18426,86 , 18621,31 , 9922,32 , 9954,60 , 10014,18 , 9922,32 , 9954,60 , 10014,18 , 0,2 , 0,2 , {73,78,82}, 123,1 , 11384,26 , 4,4 , 8,6 , 3687,6 , 3693,9 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
+ { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 510,5 , 510,5 , 515,8 , 523,7 , 287,6 , 1098,19 , 37,5 , 508,28 , 18652,63 , 18715,98 , 18652,63 , 18652,63 , 18715,98 , 18813,62 , 10032,23 , 10055,68 , 10032,23 , 10032,23 , 10055,68 , 10032,23 , 284,10 , 274,10 , {84,72,66}, 313,1 , 11410,13 , 4,4 , 8,6 , 3702,3 , 3702,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
+ { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {67,78,89}, 314,1 , 11423,13 , 14,5 , 4,0 , 3705,8 , 3713,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
+ { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {73,78,82}, 123,1 , 11436,22 , 14,5 , 4,0 , 3705,8 , 3719,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
+ { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1117,23 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 10292,29 , 10292,29 , 10321,14 , 10292,29 , 10292,29 , 10321,14 , 301,7 , 292,7 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 3726,4 , 109,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
+ { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1140,23 , 18,7 , 25,12 , 19141,46 , 19187,54 , 1050,24 , 19141,46 , 19187,54 , 1050,24 , 10335,29 , 10335,29 , 10321,14 , 10335,29 , 10335,29 , 10321,14 , 301,7 , 292,7 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 3726,4 , 3730,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
+ { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 530,8 , 530,8 , 530,8 , 530,8 , 287,6 , 99,16 , 37,5 , 8,10 , 19241,51 , 19292,87 , 19379,24 , 19241,51 , 19292,87 , 19379,24 , 10364,29 , 10393,60 , 10453,14 , 10364,29 , 10393,60 , 10453,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 0,7 , 14,5 , 4,0 , 3734,13 , 1339,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
+ { 124, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 19403,48 , 19451,122 , 158,27 , 19403,48 , 19451,122 , 158,27 , 10467,27 , 10494,72 , 85,14 , 10467,27 , 10494,72 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3747,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/SouthAfrica
+ { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {84,82,89}, 315,1 , 11474,18 , 25,5 , 30,7 , 3755,6 , 3761,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
+ { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {69,85,82}, 19,1 , 81,11 , 25,5 , 30,7 , 3755,6 , 3768,23 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
+ { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 546,8 , 546,8 , 187,8 , 1188,22 , 37,5 , 8,10 , 19720,48 , 19768,95 , 19863,24 , 19887,67 , 19954,87 , 19863,24 , 10662,21 , 10683,56 , 10739,14 , 10662,21 , 10683,56 , 10739,14 , 310,2 , 301,2 , {85,65,72}, 279,1 , 11492,49 , 25,5 , 4,0 , 3791,10 , 3801,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
+ { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {80,75,82}, 180,2 , 11541,21 , 4,4 , 4,0 , 3808,4 , 3812,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
+ { 130, 1, 100, 46, 44, 59, 37, 1776, 45, 43, 1602, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {73,78,82}, 123,1 , 11562,18 , 14,5 , 4,0 , 3808,4 , 3819,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
+ { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 14970,24 , 17980,48 , 18028,71 , 14970,24 , 10789,28 , 10817,53 , 10870,14 , 10789,28 , 10817,53 , 10870,14 , 0,2 , 0,2 , {85,90,83}, 316,3 , 11580,21 , 14,5 , 4,0 , 3824,5 , 3829,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
+ { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 1210,33 , 61,4 , 408,11 , 20107,48 , 13771,68 , 158,27 , 20107,48 , 13771,68 , 158,27 , 10884,21 , 7208,49 , 85,14 , 10884,21 , 7208,49 , 85,14 , 0,2 , 0,2 , {65,70,78}, 263,1 , 11601,13 , 25,5 , 4,0 , 3839,6 , 2782,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
+ { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 20155,52 , 20207,77 , 20284,24 , 20155,52 , 20207,77 , 20284,24 , 10905,34 , 10939,61 , 11000,14 , 10905,34 , 10939,61 , 11000,14 , 0,2 , 0,2 , {85,90,83}, 319,4 , 11614,23 , 14,5 , 4,0 , 3845,9 , 3854,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
+ { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 573,8 , 573,8 , 141,10 , 1243,31 , 37,5 , 8,10 , 20308,75 , 20383,130 , 158,27 , 20308,75 , 20383,130 , 158,27 , 11014,33 , 11047,55 , 11102,21 , 11014,33 , 11047,55 , 11102,21 , 321,2 , 312,2 , {86,78,68}, 323,1 , 11637,20 , 25,5 , 4,0 , 3865,10 , 3875,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
+ { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 135,7 , 135,7 , 141,10 , 10,17 , 37,5 , 8,10 , 20513,52 , 20565,87 , 20652,26 , 20678,62 , 20565,87 , 20652,26 , 11123,29 , 11152,77 , 11229,15 , 11244,30 , 11152,77 , 11229,15 , 0,2 , 0,2 , {71,66,80}, 171,1 , 11657,154 , 4,4 , 4,0 , 3883,7 , 3890,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/UnitedKingdom
+ { 136, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 20740,48 , 20788,91 , 158,27 , 20740,48 , 20788,91 , 158,27 , 11274,28 , 11302,61 , 85,14 , 11274,28 , 11302,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3906,8 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/SouthAfrica
+ { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 20879,73 , 20952,121 , 158,27 , 20879,73 , 20952,121 , 158,27 , 11363,44 , 11407,69 , 85,14 , 11363,44 , 11407,69 , 85,14 , 323,5 , 314,5 , {78,71,78}, 182,1 , 11811,34 , 4,4 , 8,6 , 3914,10 , 3924,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
+ { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 581,9 , 590,10 , 72,10 , 82,17 , 18,7 , 25,12 , 21073,48 , 21121,104 , 134,24 , 21073,48 , 21225,90 , 134,24 , 11476,28 , 11504,68 , 11572,14 , 11476,28 , 11504,68 , 11572,14 , 328,7 , 319,8 , {90,65,82}, 11,1 , 11845,27 , 4,4 , 8,6 , 3942,7 , 3949,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/SouthAfrica
+ { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 11586,28 , 11614,51 , 2309,14 , 11665,28 , 11614,51 , 2309,14 , 335,9 , 327,11 , {78,79,75}, 157,2 , 11872,42 , 25,5 , 4,0 , 3966,7 , 3973,5 , 2, 1, 1, 6, 7 }, // NorwegianNynorsk/Latin/Norway
+ { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 118,7 , 118,7 , 1274,9 , 981,20 , 37,5 , 8,10 , 15431,48 , 21315,83 , 15560,24 , 15431,48 , 21315,83 , 15560,24 , 2032,28 , 2060,58 , 85,14 , 2032,28 , 2060,58 , 85,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 11914,218 , 14,5 , 4,0 , 3978,8 , 587,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/BosniaAndHerzegowina
+ { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 37,5 , 8,10 , 15302,48 , 15584,83 , 11981,24 , 15302,48 , 15584,83 , 11981,24 , 8357,28 , 8385,54 , 8261,14 , 8357,28 , 8385,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 288,2 , 12132,195 , 25,5 , 4,0 , 3986,8 , 3138,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/BosniaAndHerzegowina
+ { 144, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 82,17 , 37,5 , 8,10 , 21398,102 , 21500,140 , 158,27 , 21398,102 , 21500,140 , 158,27 , 11693,30 , 11723,57 , 85,14 , 11693,30 , 11723,57 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 3994,5 , 3999,14 , 2, 1, 1, 6, 7 }, // Manx/Latin/UnitedKingdom
+ { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 21640,46 , 21686,124 , 158,27 , 21640,46 , 21686,124 , 158,27 , 11780,28 , 11808,60 , 85,14 , 11780,28 , 11808,60 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 4013,8 , 3999,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/UnitedKingdom
+ { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 21810,48 , 21858,192 , 158,27 , 21810,48 , 21858,192 , 158,27 , 11868,28 , 11896,49 , 11945,14 , 11868,28 , 11896,49 , 11945,14 , 344,2 , 338,2 , {71,72,83}, 173,3 , 12327,17 , 4,4 , 4,0 , 4021,4 , 4025,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
+ { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 99,16 , 18,7 , 25,12 , 22050,87 , 22050,87 , 158,27 , 22050,87 , 22050,87 , 158,27 , 6771,32 , 11959,55 , 85,14 , 6771,32 , 11959,55 , 85,14 , 346,5 , 340,5 , {73,78,82}, 123,1 , 0,7 , 14,5 , 4,0 , 4030,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
+ { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22137,48 , 22185,86 , 158,27 , 22137,48 , 22185,86 , 158,27 , 12014,29 , 12043,57 , 85,14 , 12014,29 , 12043,57 , 85,14 , 351,4 , 345,4 , {78,71,78}, 182,1 , 12344,12 , 4,4 , 8,6 , 4036,4 , 1113,7 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
+ { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22271,48 , 22319,189 , 22508,24 , 22271,48 , 22319,189 , 22508,24 , 12100,28 , 12128,74 , 12202,14 , 12100,28 , 12128,74 , 12202,14 , 355,9 , 349,7 , {75,69,83}, 2,3 , 12356,23 , 4,4 , 8,6 , 4040,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
+ { 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1283,22 , 18,7 , 25,12 , 22532,47 , 22579,77 , 22656,24 , 22532,47 , 22579,77 , 22656,24 , 12216,26 , 12242,43 , 12285,14 , 12216,26 , 12242,43 , 12285,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4047,3 , 3730,4 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea
+ { 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1305,21 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12299,27 , 12326,41 , 12367,14 , 12299,27 , 12326,41 , 12367,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4050,3 , 3730,4 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea
+ { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 1326,27 , 37,5 , 8,10 , 22680,48 , 22728,77 , 22805,24 , 22680,48 , 22728,77 , 22805,24 , 12381,28 , 12409,50 , 3070,14 , 12381,28 , 12409,50 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 14,5 , 4,0 , 4053,6 , 4059,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
+ { 160, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 22829,48 , 22877,111 , 158,27 , 22829,48 , 22877,111 , 158,27 , 12459,27 , 12486,70 , 85,14 , 12459,27 , 12486,70 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4065,9 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/SouthAfrica
+ { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {71,72,83}, 173,3 , 12379,37 , 4,4 , 8,6 , 4074,6 , 4080,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
+ { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {88,79,70}, 209,3 , 12416,106 , 4,4 , 8,6 , 4074,6 , 4092,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
+ { 162, 14, 69, 46, 8217, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1376,22 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12642,27 , 12642,27 , 12669,14 , 12642,27 , 12642,27 , 12669,14 , 0,2 , 0,2 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 4103,5 , 109,5 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia
+ { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 10,17 , 18,7 , 25,12 , 23147,59 , 23206,95 , 158,27 , 23147,59 , 23206,95 , 158,27 , 12683,21 , 12704,57 , 85,14 , 12683,21 , 12704,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 0,7 , 4,4 , 8,6 , 4108,14 , 4122,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/UnitedStates
+ { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 621,8 , 621,8 , 518,6 , 1398,18 , 37,5 , 8,10 , 23301,48 , 23349,88 , 23437,24 , 23301,48 , 23349,88 , 23437,24 , 12761,28 , 12789,55 , 12844,14 , 12858,28 , 12789,55 , 12844,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 12522,22 , 4,4 , 8,6 , 4141,8 , 4149,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
+ { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 23461,86 , 134,24 , 6990,48 , 23461,86 , 134,24 , 12886,28 , 12914,63 , 3471,14 , 12886,28 , 12914,63 , 3471,14 , 94,5 , 361,4 , {67,72,70}, 230,3 , 12544,55 , 25,5 , 4,0 , 4158,16 , 4174,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
+ { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 158,27 , 23547,38 , 158,27 , 158,27 , 23547,38 , 158,27 , 12977,21 , 12998,28 , 13026,14 , 12977,21 , 12998,28 , 13026,14 , 367,2 , 365,2 , {67,78,89}, 314,1 , 0,7 , 14,5 , 4,0 , 4181,3 , 4184,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
+ { 171, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23585,48 , 23633,100 , 158,27 , 23585,48 , 23633,100 , 158,27 , 13040,27 , 13067,66 , 85,14 , 13040,27 , 13067,66 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4186,10 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/SouthAfrica
+ { 172, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23733,48 , 23781,94 , 158,27 , 23733,48 , 23781,94 , 158,27 , 13133,27 , 13160,63 , 85,14 , 13133,27 , 13160,63 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4196,16 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/SouthAfrica
+ { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 23875,59 , 23934,145 , 24079,24 , 23875,59 , 23934,145 , 24079,24 , 13223,33 , 13256,75 , 13331,14 , 13223,33 , 13256,75 , 13331,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 12599,63 , 25,5 , 4,0 , 4212,15 , 4227,5 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Norway
+ { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 24103,85 , 23934,145 , 24079,24 , 24103,85 , 23934,145 , 24079,24 , 13223,33 , 13345,65 , 13410,14 , 13223,33 , 13345,65 , 13410,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 12662,23 , 25,5 , 4,0 , 4212,15 , 4232,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
+ { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24188,48 , 24236,88 , 24324,24 , 24188,48 , 24236,88 , 24324,24 , 13424,28 , 13452,62 , 13514,14 , 13424,28 , 13452,62 , 13514,14 , 369,5 , 367,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4238,8 , 1012,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
+ { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24348,48 , 24396,221 , 24617,24 , 24348,48 , 24396,221 , 24617,24 , 13528,28 , 13556,105 , 13661,14 , 13528,28 , 13556,105 , 13661,14 , 374,10 , 377,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4246,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
+ { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 24641,48 , 24689,77 , 24766,24 , 24641,48 , 24689,77 , 24766,24 , 13675,28 , 13703,59 , 13762,14 , 13675,28 , 13703,59 , 13762,14 , 384,6 , 387,7 , {88,79,70}, 209,3 , 12709,26 , 25,5 , 4,0 , 4253,6 , 4259,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
+ { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24790,48 , 24838,185 , 25023,24 , 24790,48 , 24838,185 , 25023,24 , 13776,28 , 13804,63 , 13867,14 , 13776,28 , 13804,63 , 13867,14 , 390,6 , 394,8 , {75,69,83}, 2,3 , 12735,23 , 4,4 , 8,6 , 4267,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
+ { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25047,48 , 25095,173 , 25268,24 , 25047,48 , 25095,173 , 25268,24 , 13881,28 , 13909,105 , 14014,14 , 13881,28 , 13909,105 , 14014,14 , 396,7 , 402,5 , {75,69,83}, 2,3 , 12758,25 , 4,4 , 8,6 , 4273,8 , 1012,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
+ { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 897,27 , 37,5 , 8,10 , 25292,48 , 25340,88 , 134,24 , 25292,48 , 25340,88 , 134,24 , 14028,28 , 14056,55 , 14111,14 , 14028,28 , 14056,55 , 14111,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 12783,28 , 0,4 , 4,0 , 4281,4 , 2908,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
+ { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25428,52 , 25480,112 , 25592,24 , 25428,52 , 25480,112 , 25592,24 , 14125,28 , 14153,50 , 14203,14 , 14125,28 , 14153,50 , 14203,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 12811,24 , 4,4 , 8,6 , 4186,10 , 1497,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
+ { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25616,39 , 25655,194 , 25849,24 , 25616,39 , 25655,194 , 25849,24 , 14217,29 , 14246,65 , 14311,14 , 14217,29 , 14246,65 , 14311,14 , 403,8 , 407,7 , {84,90,83}, 192,3 , 12835,25 , 4,4 , 4,0 , 4285,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
+ { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 25873,48 , 25921,81 , 26002,24 , 25873,48 , 25921,81 , 26002,24 , 14325,30 , 14355,47 , 85,14 , 14325,30 , 14355,47 , 85,14 , 411,6 , 414,8 , {77,65,68}, 0,0 , 12860,21 , 0,4 , 4,0 , 4294,8 , 4302,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
+ { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26026,48 , 26074,81 , 26155,24 , 26026,48 , 26074,81 , 26155,24 , 14402,30 , 14432,48 , 85,14 , 14402,30 , 14432,48 , 85,14 , 417,6 , 422,8 , {77,65,68}, 0,0 , 12881,21 , 0,4 , 4,0 , 4308,9 , 4317,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
+ { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26179,48 , 26227,84 , 26311,24 , 26179,48 , 26227,84 , 26311,24 , 14480,30 , 14510,51 , 14561,14 , 14480,30 , 14510,51 , 14561,14 , 423,7 , 430,9 , {68,90,68}, 207,2 , 12902,21 , 0,4 , 4,0 , 4323,9 , 4332,8 , 2, 1, 6, 4, 5 }, // Kabyle/Latin/Algeria
+ { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4340,10 , 1387,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
+ { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26535,48 , 26583,254 , 26837,24 , 26535,48 , 26583,254 , 26837,24 , 14691,28 , 14719,82 , 14801,14 , 14691,28 , 14719,82 , 14801,14 , 430,7 , 439,7 , {84,90,83}, 192,3 , 12949,29 , 0,4 , 4,0 , 4350,6 , 4356,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
+ { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4366,8 , 1331,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
+ { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26948,47 , 26995,92 , 27087,24 , 26948,47 , 26995,92 , 27087,24 , 14919,28 , 14947,44 , 14991,14 , 14919,28 , 14947,44 , 14991,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13005,24 , 4,4 , 8,6 , 4374,9 , 1842,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
+ { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27111,48 , 27159,207 , 27366,24 , 27111,48 , 27159,207 , 27366,24 , 15005,28 , 15033,64 , 15097,14 , 15005,28 , 15033,64 , 15097,14 , 442,2 , 455,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4383,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
+ { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 27390,36 , 27426,58 , 27484,24 , 27390,36 , 27426,58 , 27484,24 , 15111,28 , 15139,49 , 15188,14 , 15111,28 , 15139,49 , 15188,14 , 444,3 , 457,6 , {85,83,68}, 12,1 , 13029,19 , 4,4 , 8,6 , 4389,3 , 4392,4 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/UnitedStates
+ { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 27508,47 , 27555,68 , 27623,24 , 27508,47 , 27555,68 , 27623,24 , 15202,27 , 15229,48 , 15277,14 , 15202,27 , 15229,48 , 15277,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 13048,21 , 14,5 , 4,0 , 4396,14 , 4410,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
+ { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 27647,264 , 134,24 , 17628,48 , 27647,264 , 134,24 , 15291,28 , 15319,133 , 14311,14 , 15291,28 , 15319,133 , 14311,14 , 447,4 , 463,5 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 8,6 , 4415,10 , 1331,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
+ { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27911,83 , 27994,111 , 28105,24 , 27911,83 , 27994,111 , 28105,24 , 15452,36 , 15488,63 , 15551,14 , 15452,36 , 15488,63 , 15551,14 , 451,3 , 468,3 , {84,90,83}, 192,3 , 13069,29 , 14,5 , 4,0 , 4425,8 , 4433,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
+ { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 15565,28 , 15593,66 , 15659,14 , 15565,28 , 15593,66 , 15659,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 13098,26 , 0,4 , 4,0 , 4442,7 , 4449,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
+ { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28274,48 , 28322,83 , 28405,24 , 28274,48 , 28322,83 , 28405,24 , 15673,80 , 15673,80 , 85,14 , 15673,80 , 15673,80 , 85,14 , 454,8 , 471,7 , {90,77,87}, 202,2 , 0,7 , 4,4 , 8,6 , 4456,9 , 1491,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
+ { 196, 7, 39, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 453,7 , 453,7 , 364,8 , 1416,27 , 37,5 , 8,10 , 28429,48 , 28477,86 , 134,24 , 28429,48 , 28477,86 , 134,24 , 15753,28 , 15781,73 , 15854,14 , 15753,28 , 15781,73 , 15854,14 , 89,2 , 88,2 , {67,86,69}, 0,0 , 13124,25 , 0,4 , 4,0 , 4465,12 , 4477,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/CapeVerde
+ { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28563,48 , 28611,86 , 28697,24 , 28563,48 , 28611,86 , 28697,24 , 15868,28 , 15896,51 , 15947,14 , 15868,28 , 15896,51 , 15947,14 , 462,2 , 478,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4487,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
+ { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28721,48 , 28769,111 , 28880,24 , 28721,48 , 28769,111 , 28880,24 , 15961,28 , 15989,93 , 16082,14 , 15961,28 , 15989,93 , 16082,14 , 464,4 , 480,4 , {75,69,83}, 2,3 , 13149,26 , 4,4 , 8,6 , 4493,8 , 4501,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
+ { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 0,48 , 28904,136 , 134,24 , 0,48 , 28904,136 , 134,24 , 16096,23 , 16119,92 , 16211,14 , 16096,23 , 16119,92 , 16211,14 , 468,7 , 484,5 , {78,65,68}, 12,1 , 13175,22 , 4,4 , 4,0 , 4513,13 , 4526,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
+ { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4534,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
+ { 201, 7, 82, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 347,8 , 347,8 , 1443,10 , 1453,23 , 37,5 , 8,10 , 29040,59 , 29099,87 , 134,24 , 29186,48 , 29099,87 , 134,24 , 16225,28 , 16253,72 , 3471,14 , 16225,28 , 16253,72 , 3471,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 81,11 , 25,5 , 4,0 , 4543,6 , 4549,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
+ { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {75,69,83}, 2,3 , 13197,25 , 4,4 , 8,6 , 4560,3 , 1012,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
+ { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {84,90,83}, 192,3 , 13222,28 , 4,4 , 8,6 , 4560,3 , 4563,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
+ { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 16383,35 , 16418,65 , 16483,14 , 16383,35 , 16418,65 , 16483,14 , 484,6 , 495,6 , {85,71,88}, 197,3 , 13098,26 , 25,5 , 4,0 , 4571,7 , 4449,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
+ { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29417,48 , 17676,84 , 134,24 , 29417,48 , 17676,84 , 134,24 , 16497,21 , 16518,75 , 85,14 , 16497,21 , 16518,75 , 85,14 , 75,4 , 74,4 , {75,69,83}, 2,3 , 13250,23 , 4,4 , 83,6 , 4578,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
+ { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29465,48 , 17676,84 , 134,24 , 29465,48 , 17676,84 , 134,24 , 16593,28 , 9539,60 , 14905,14 , 16593,28 , 9539,60 , 14905,14 , 490,9 , 501,8 , {84,90,83}, 192,3 , 13273,28 , 25,5 , 4,0 , 4585,6 , 4591,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
+ { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {85,71,88}, 197,3 , 13301,28 , 4,4 , 8,6 , 4599,6 , 1387,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
+ { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {75,69,83}, 2,3 , 13329,27 , 4,4 , 8,6 , 4599,6 , 4605,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
{ 207, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 344,48 , 392,118 , 510,24 , 344,48 , 392,118 , 510,24 , 16732,28 , 16760,56 , 16816,14 , 16732,28 , 16760,56 , 16816,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 0,0 , 43,7 , 2, 1, 1, 6, 7 }, // Saho/Latin/Eritrea
- { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 16830,28 , 16858,53 , 16911,14 , 16830,28 , 16858,53 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4592,11 , 4603,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
- { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 0,4 , 4,0 , 4608,6 , 1325,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
- { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29837,48 , 29885,186 , 30071,24 , 29837,48 , 29885,186 , 30071,24 , 16925,28 , 16953,69 , 17022,14 , 16925,28 , 16953,69 , 17022,14 , 514,2 , 521,2 , {75,69,83}, 2,3 , 13379,23 , 0,4 , 4,0 , 4614,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
- { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4620,6 , 1381,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
- { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 30095,48 , 30143,86 , 30229,24 , 30095,48 , 30143,86 , 30229,24 , 17036,28 , 17064,48 , 17112,14 , 17036,28 , 17064,48 , 17112,14 , 516,9 , 523,10 , {77,65,68}, 0,0 , 13402,22 , 25,5 , 4,0 , 4626,8 , 4634,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
- { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4640,15 , 4603,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
- { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 30253,84 , 134,24 , 17628,48 , 30253,84 , 134,24 , 17208,28 , 17236,63 , 9599,14 , 17208,28 , 17236,63 , 9599,14 , 525,5 , 533,8 , {84,90,83}, 192,3 , 11152,27 , 0,4 , 4,0 , 4655,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
- { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 30337,88 , 30337,88 , 30425,31 , 30337,88 , 30337,88 , 30425,31 , 17299,33 , 17332,54 , 17386,19 , 17299,33 , 17332,54 , 17386,19 , 530,3 , 541,6 , {73,78,82}, 122,1 , 13424,10 , 14,5 , 4,0 , 4664,4 , 2276,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
- { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30456,49 , 30505,99 , 30604,24 , 30456,49 , 30505,99 , 30604,24 , 17405,28 , 17433,50 , 17483,14 , 17405,28 , 17433,50 , 17483,14 , 533,5 , 547,6 , {67,68,70}, 217,2 , 13434,24 , 0,4 , 4,0 , 4668,8 , 4676,16 , 2, 1, 1, 6, 7 }, // LubaKatanga/Latin/CongoKinshasa
- { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30628,48 , 30676,195 , 30871,24 , 30628,48 , 30676,195 , 30871,24 , 17497,28 , 17525,72 , 17597,14 , 17497,28 , 17525,72 , 17597,14 , 538,3 , 553,3 , {88,65,70}, 36,4 , 13458,21 , 0,4 , 4,0 , 4692,5 , 4697,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
- { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30895,48 , 30943,90 , 31033,24 , 30895,48 , 30943,90 , 31033,24 , 17611,28 , 17639,70 , 17709,14 , 17611,28 , 17639,70 , 17709,14 , 541,10 , 556,9 , {88,65,70}, 36,4 , 13479,22 , 25,5 , 4,0 , 4704,5 , 4709,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
- { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17723,53 , 17776,14 , 17126,28 , 17723,53 , 17776,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4717,10 , 4727,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
- { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31057,49 , 31106,99 , 31205,24 , 31057,49 , 31106,99 , 31205,24 , 17790,28 , 17818,45 , 17863,14 , 17790,28 , 17818,45 , 17863,14 , 559,5 , 575,6 , {88,65,70}, 36,4 , 0,7 , 25,5 , 4,0 , 4732,5 , 1615,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
- { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31229,36 , 31265,82 , 31347,24 , 31229,36 , 31265,82 , 31347,24 , 17877,28 , 17905,50 , 17955,14 , 17877,28 , 17905,50 , 17955,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13501,23 , 25,5 , 4,0 , 4737,5 , 4742,7 , 0, 0, 1, 6, 7 }, // JolaFonyi/Latin/Senegal
- { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31371,50 , 31421,141 , 31562,24 , 31371,50 , 31421,141 , 31562,24 , 17969,30 , 17999,85 , 18084,14 , 17969,30 , 17999,85 , 18084,14 , 564,7 , 581,9 , {88,65,70}, 36,4 , 13524,23 , 25,5 , 4,0 , 4749,6 , 4755,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
- { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31586,39 , 31625,191 , 158,27 , 31586,39 , 31625,191 , 158,27 , 18098,29 , 18127,45 , 18172,14 , 18098,29 , 18127,45 , 18172,14 , 571,6 , 590,7 , {88,65,70}, 36,4 , 13547,11 , 25,5 , 4,0 , 4762,5 , 4767,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
- { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 31816,48 , 31864,213 , 32077,24 , 31816,48 , 31864,213 , 32077,24 , 18186,28 , 18214,59 , 18273,14 , 18186,28 , 18214,59 , 18273,14 , 577,8 , 597,10 , {77,90,78}, 269,3 , 0,7 , 14,5 , 4,0 , 4774,5 , 4779,10 , 2, 1, 7, 6, 7 }, // MakhuwaMeetto/Latin/Mozambique
- { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32101,48 , 32149,139 , 32288,24 , 32101,48 , 32149,139 , 32288,24 , 18287,28 , 18315,74 , 18389,14 , 18287,28 , 18315,74 , 18389,14 , 585,5 , 607,5 , {88,65,70}, 36,4 , 13558,17 , 4,4 , 8,6 , 4789,6 , 4795,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
- { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32312,51 , 32363,143 , 158,27 , 32312,51 , 32363,143 , 158,27 , 18403,30 , 18433,89 , 18522,14 , 18403,30 , 18433,89 , 18522,14 , 590,4 , 612,4 , {88,65,70}, 36,4 , 13575,20 , 25,5 , 4,0 , 4802,6 , 4808,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
- { 247, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1476,9 , 99,16 , 18,7 , 560,12 , 32506,54 , 32560,96 , 32656,24 , 32506,54 , 32560,96 , 32656,24 , 18536,38 , 18574,79 , 18653,14 , 18536,38 , 18574,79 , 18653,14 , 594,2 , 616,2 , {83,68,71}, 0,0 , 0,7 , 4,4 , 8,6 , 4815,9 , 4824,5 , 2, 1, 6, 5, 6 }, // Nuer/Latin/Sudan
- { 248, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1485,6 , 1491,30 , 37,5 , 8,10 , 32680,75 , 32755,121 , 32876,24 , 32680,75 , 32755,121 , 32876,24 , 18667,21 , 18688,73 , 18761,14 , 18667,21 , 18688,73 , 18761,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 0,7 , 14,5 , 4,0 , 4829,9 , 0,0 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
- { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 32900,48 , 32948,117 , 158,27 , 32900,48 , 32948,117 , 158,27 , 18775,28 , 18803,60 , 18863,14 , 18775,28 , 18803,60 , 18863,14 , 596,9 , 618,9 , {84,90,83}, 192,3 , 13595,25 , 0,4 , 4,0 , 4838,9 , 4847,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
- { 250, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33065,48 , 33113,188 , 33301,24 , 33065,48 , 33113,188 , 33301,24 , 18877,28 , 18905,93 , 18998,14 , 18877,28 , 18905,93 , 18998,14 , 605,10 , 627,10 , {67,68,70}, 217,2 , 13620,23 , 4,4 , 4,0 , 4856,18 , 4874,32 , 2, 1, 1, 6, 7 }, // Congo Swahili/Latin/CongoKinshasa
- { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4906,13 , 4727,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
- { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33325,50 , 33325,50 , 158,27 , 33325,50 , 33325,50 , 158,27 , 19012,30 , 19012,30 , 85,14 , 19012,30 , 19012,30 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13643,15 , 4,4 , 8,6 , 4919,2 , 4921,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
- { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33375,81 , 33375,81 , 158,27 , 33375,81 , 33375,81 , 158,27 , 19042,48 , 19042,48 , 85,14 , 19042,48 , 19042,48 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13658,20 , 4,4 , 8,6 , 4925,3 , 4928,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
- { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 72,10 , 462,18 , 37,5 , 8,10 , 33456,48 , 33504,99 , 33603,24 , 33456,48 , 33504,99 , 33603,24 , 19090,28 , 19118,53 , 19171,14 , 19090,28 , 19118,53 , 19171,14 , 0,2 , 0,2 , {67,72,70}, 0,0 , 0,7 , 14,5 , 4,0 , 4936,6 , 4942,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
- { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33627,51 , 33678,191 , 158,27 , 33627,51 , 33678,191 , 158,27 , 19185,21 , 19206,71 , 19277,14 , 19185,21 , 19206,71 , 19277,14 , 615,8 , 637,8 , {88,65,70}, 36,4 , 0,7 , 25,5 , 30,7 , 4948,6 , 4954,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
- { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 453,7 , 453,7 , 287,6 , 1521,23 , 37,5 , 8,10 , 33869,48 , 33917,85 , 34002,24 , 34026,48 , 34074,117 , 34002,24 , 19291,28 , 19319,54 , 3272,14 , 19291,28 , 19319,54 , 3272,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 4961,9 , 2048,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
- { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 629,11 , 629,11 , 640,16 , 656,9 , 72,10 , 269,18 , 37,5 , 8,10 , 34191,174 , 34191,174 , 158,27 , 34191,174 , 34191,174 , 158,27 , 19373,60 , 19373,60 , 19433,25 , 19373,60 , 19373,60 , 19433,25 , 623,8 , 645,13 , {88,65,70}, 36,4 , 13678,12 , 14,5 , 4,0 , 4970,5 , 4975,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
- { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1544,10 , 82,17 , 37,5 , 8,10 , 34365,102 , 34365,102 , 158,27 , 34365,102 , 34365,102 , 158,27 , 19458,54 , 19458,54 , 19512,21 , 19458,54 , 19458,54 , 19512,21 , 0,2 , 0,2 , {88,65,70}, 36,4 , 13690,16 , 14,5 , 4,0 , 4982,4 , 4986,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
- { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 269,18 , 37,5 , 8,10 , 34467,137 , 34604,142 , 34746,36 , 34467,137 , 34604,142 , 34746,36 , 19533,49 , 19533,49 , 19582,21 , 19533,49 , 19533,49 , 19582,21 , 0,2 , 0,2 , {88,65,70}, 36,4 , 13706,12 , 14,5 , 4,0 , 4993,5 , 4998,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
- { 260, 7, 37, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1554,32 , 37,5 , 8,10 , 34782,164 , 34782,164 , 158,27 , 34782,164 , 34782,164 , 158,27 , 19603,111 , 19603,111 , 85,14 , 19603,111 , 19603,111 , 85,14 , 631,9 , 658,8 , {88,65,70}, 36,4 , 13718,16 , 14,5 , 4,0 , 5005,16 , 5021,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
+ { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 16830,28 , 16858,53 , 16911,14 , 16830,28 , 16858,53 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4610,11 , 4621,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
+ { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 0,4 , 4,0 , 4626,6 , 1331,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
+ { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29837,48 , 29885,186 , 30071,24 , 29837,48 , 29885,186 , 30071,24 , 16925,28 , 16953,69 , 17022,14 , 16925,28 , 16953,69 , 17022,14 , 514,2 , 521,2 , {75,69,83}, 2,3 , 13379,23 , 0,4 , 4,0 , 4632,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
+ { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4638,6 , 1387,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
+ { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 30095,48 , 30143,86 , 30229,24 , 30095,48 , 30143,86 , 30229,24 , 17036,28 , 17064,48 , 17112,14 , 17036,28 , 17064,48 , 17112,14 , 516,9 , 523,10 , {77,65,68}, 0,0 , 13402,22 , 25,5 , 4,0 , 4644,8 , 4652,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
+ { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4658,15 , 4621,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
+ { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 30253,84 , 134,24 , 17628,48 , 30253,84 , 134,24 , 17208,28 , 17236,63 , 9599,14 , 17208,28 , 17236,63 , 9599,14 , 525,5 , 533,8 , {84,90,83}, 192,3 , 11152,27 , 0,4 , 4,0 , 4673,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
+ { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 30337,88 , 30337,88 , 30425,31 , 30337,88 , 30337,88 , 30425,31 , 17299,33 , 17332,54 , 17386,19 , 17299,33 , 17332,54 , 17386,19 , 530,3 , 541,6 , {73,78,82}, 123,1 , 13424,10 , 14,5 , 4,0 , 4682,4 , 2282,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
+ { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30456,49 , 30505,99 , 30604,24 , 30456,49 , 30505,99 , 30604,24 , 17405,28 , 17433,50 , 17483,14 , 17405,28 , 17433,50 , 17483,14 , 533,5 , 547,6 , {67,68,70}, 217,2 , 13434,24 , 0,4 , 4,0 , 4686,8 , 4694,16 , 2, 1, 1, 6, 7 }, // LubaKatanga/Latin/CongoKinshasa
+ { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30628,48 , 30676,195 , 30871,24 , 30628,48 , 30676,195 , 30871,24 , 17497,28 , 17525,72 , 17597,14 , 17497,28 , 17525,72 , 17597,14 , 538,3 , 553,3 , {88,65,70}, 37,4 , 13458,21 , 0,4 , 4,0 , 4710,5 , 4715,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
+ { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30895,48 , 30943,90 , 31033,24 , 30895,48 , 30943,90 , 31033,24 , 17611,28 , 17639,70 , 17709,14 , 17611,28 , 17639,70 , 17709,14 , 541,10 , 556,9 , {88,65,70}, 37,4 , 13479,22 , 25,5 , 4,0 , 4722,5 , 4727,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
+ { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17723,53 , 17776,14 , 17126,28 , 17723,53 , 17776,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4735,10 , 4745,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
+ { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31057,49 , 31106,99 , 31205,24 , 31057,49 , 31106,99 , 31205,24 , 17790,28 , 17818,45 , 17863,14 , 17790,28 , 17818,45 , 17863,14 , 559,5 , 575,6 , {88,65,70}, 37,4 , 0,7 , 25,5 , 4,0 , 4750,5 , 1621,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
+ { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31229,36 , 31265,82 , 31347,24 , 31229,36 , 31265,82 , 31347,24 , 17877,28 , 17905,50 , 17955,14 , 17877,28 , 17905,50 , 17955,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13501,23 , 25,5 , 4,0 , 4755,5 , 4760,7 , 0, 0, 1, 6, 7 }, // JolaFonyi/Latin/Senegal
+ { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31371,50 , 31421,141 , 31562,24 , 31371,50 , 31421,141 , 31562,24 , 17969,30 , 17999,85 , 18084,14 , 17969,30 , 17999,85 , 18084,14 , 564,7 , 581,9 , {88,65,70}, 37,4 , 13524,23 , 25,5 , 4,0 , 4767,6 , 4773,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
+ { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31586,39 , 31625,191 , 158,27 , 31586,39 , 31625,191 , 158,27 , 18098,29 , 18127,45 , 18172,14 , 18098,29 , 18127,45 , 18172,14 , 571,6 , 590,7 , {88,65,70}, 37,4 , 13547,11 , 25,5 , 4,0 , 4780,5 , 4785,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
+ { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 31816,48 , 31864,213 , 32077,24 , 31816,48 , 31864,213 , 32077,24 , 18186,28 , 18214,59 , 18273,14 , 18186,28 , 18214,59 , 18273,14 , 577,8 , 597,10 , {77,90,78}, 269,3 , 0,7 , 14,5 , 4,0 , 4792,5 , 4797,10 , 2, 1, 7, 6, 7 }, // MakhuwaMeetto/Latin/Mozambique
+ { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32101,48 , 32149,139 , 32288,24 , 32101,48 , 32149,139 , 32288,24 , 18287,28 , 18315,74 , 18389,14 , 18287,28 , 18315,74 , 18389,14 , 585,5 , 607,5 , {88,65,70}, 37,4 , 13558,17 , 4,4 , 8,6 , 4807,6 , 4813,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
+ { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32312,51 , 32363,143 , 158,27 , 32312,51 , 32363,143 , 158,27 , 18403,30 , 18433,89 , 18522,14 , 18403,30 , 18433,89 , 18522,14 , 590,4 , 612,4 , {88,65,70}, 37,4 , 13575,20 , 25,5 , 4,0 , 4820,6 , 4826,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
+ { 247, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1476,9 , 99,16 , 18,7 , 560,12 , 32506,54 , 32560,96 , 32656,24 , 32506,54 , 32560,96 , 32656,24 , 18536,38 , 18574,79 , 18653,14 , 18536,38 , 18574,79 , 18653,14 , 594,2 , 616,2 , {83,68,71}, 0,0 , 0,7 , 4,4 , 8,6 , 4833,9 , 4842,5 , 2, 1, 6, 5, 6 }, // Nuer/Latin/Sudan
+ { 248, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1485,6 , 1491,30 , 37,5 , 8,10 , 32680,75 , 32755,121 , 32876,24 , 32680,75 , 32755,121 , 32876,24 , 18667,21 , 18688,73 , 18761,14 , 18667,21 , 18688,73 , 18761,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 0,7 , 14,5 , 4,0 , 4847,9 , 0,0 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
+ { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 32900,48 , 32948,117 , 158,27 , 32900,48 , 32948,117 , 158,27 , 18775,28 , 18803,60 , 18863,14 , 18775,28 , 18803,60 , 18863,14 , 596,9 , 618,9 , {84,90,83}, 192,3 , 13595,25 , 0,4 , 4,0 , 4856,9 , 4865,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
+ { 250, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33065,48 , 33113,188 , 33301,24 , 33065,48 , 33113,188 , 33301,24 , 18877,28 , 18905,93 , 18998,14 , 18877,28 , 18905,93 , 18998,14 , 605,10 , 627,10 , {67,68,70}, 217,2 , 13620,23 , 4,4 , 4,0 , 4874,18 , 4892,32 , 2, 1, 1, 6, 7 }, // Congo Swahili/Latin/CongoKinshasa
+ { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4924,13 , 4745,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
+ { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33325,50 , 33325,50 , 158,27 , 33325,50 , 33325,50 , 158,27 , 19012,30 , 19012,30 , 85,14 , 19012,30 , 19012,30 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13643,15 , 4,4 , 8,6 , 4937,2 , 4939,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
+ { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33375,81 , 33375,81 , 158,27 , 33375,81 , 33375,81 , 158,27 , 19042,48 , 19042,48 , 85,14 , 19042,48 , 19042,48 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13658,20 , 4,4 , 8,6 , 4943,3 , 4946,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
+ { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 72,10 , 462,18 , 37,5 , 8,10 , 33456,48 , 33504,99 , 33603,24 , 33456,48 , 33504,99 , 33603,24 , 19090,28 , 19118,53 , 19171,14 , 19090,28 , 19118,53 , 19171,14 , 0,2 , 0,2 , {67,72,70}, 0,0 , 0,7 , 14,5 , 4,0 , 4954,6 , 4960,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
+ { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33627,51 , 33678,191 , 158,27 , 33627,51 , 33678,191 , 158,27 , 19185,21 , 19206,71 , 19277,14 , 19185,21 , 19206,71 , 19277,14 , 615,8 , 637,8 , {88,65,70}, 37,4 , 0,7 , 25,5 , 30,7 , 4966,6 , 4972,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
+ { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 453,7 , 453,7 , 287,6 , 1521,23 , 37,5 , 8,10 , 33869,48 , 33917,85 , 34002,24 , 34026,48 , 34074,117 , 34002,24 , 19291,28 , 19319,54 , 3272,14 , 19291,28 , 19319,54 , 3272,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 4979,9 , 2054,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
+ { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 629,11 , 629,11 , 640,16 , 656,9 , 72,10 , 269,18 , 37,5 , 8,10 , 34191,174 , 34191,174 , 158,27 , 34191,174 , 34191,174 , 158,27 , 19373,60 , 19373,60 , 19433,25 , 19373,60 , 19373,60 , 19433,25 , 623,8 , 645,13 , {88,65,70}, 37,4 , 13678,12 , 14,5 , 4,0 , 4988,5 , 4993,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
+ { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1544,10 , 82,17 , 37,5 , 8,10 , 34365,102 , 34365,102 , 158,27 , 34365,102 , 34365,102 , 158,27 , 19458,54 , 19458,54 , 19512,21 , 19458,54 , 19458,54 , 19512,21 , 0,2 , 0,2 , {88,65,70}, 37,4 , 13690,16 , 14,5 , 4,0 , 5000,4 , 5004,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
+ { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 269,18 , 37,5 , 8,10 , 34467,137 , 34604,142 , 34746,36 , 34467,137 , 34604,142 , 34746,36 , 19533,49 , 19533,49 , 19582,21 , 19533,49 , 19533,49 , 19582,21 , 0,2 , 0,2 , {88,65,70}, 37,4 , 13706,12 , 14,5 , 4,0 , 5011,5 , 5016,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
+ { 260, 7, 37, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1554,32 , 37,5 , 8,10 , 34782,164 , 34782,164 , 158,27 , 34782,164 , 34782,164 , 158,27 , 19603,111 , 19603,111 , 85,14 , 19603,111 , 19603,111 , 85,14 , 631,9 , 658,8 , {88,65,70}, 37,4 , 13718,16 , 14,5 , 4,0 , 5023,16 , 5039,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
{ 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,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,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,0 } // trailing 0s
};
@@ -2448,19 +2451,19 @@ static const ushort months_data[] = {
0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b,
0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435,
0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430,
-0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435,
-0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458,
-0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435,
-0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435,
-0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65,
-0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75,
-0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65,
-0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72,
-0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b,
-0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74,
-0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62,
-0x61, 0x72, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73,
-0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
+0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d,
+0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61,
+0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a,
+0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61,
+0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67,
+0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61,
+0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b,
+0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b,
+0x6e, 0x3b, 0x64, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c,
+0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458,
+0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440,
+0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435,
+0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b,
0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d,
0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c,
@@ -3841,15 +3844,15 @@ static const ushort days_data[] = {
0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435,
0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447,
0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430,
-0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f,
-0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441,
-0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b,
-0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440,
-0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x6e, 0x65, 0x64,
-0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74,
-0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c,
-0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74,
-0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x425,
+0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70,
+0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73,
+0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61,
+0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72,
+0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x43d, 0x435, 0x434,
+0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442,
+0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430,
+0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442,
+0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x425,
0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b, 0x414, 0x446, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c,
0x440, 0x431, 0x3b, 0x421, 0x431, 0x442, 0x3b, 0x425, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443,
0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x414, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446,
@@ -4490,13 +4493,13 @@ static const ushort pm_data[] = {
};
static const ushort currency_symbol_data[] = {
-0x42, 0x72, 0x4b, 0x73, 0x68, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0x64, 0x65, 0x6e, 0x1265,
-0x122d, 0x62c, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46, 0x41,
-0x641, 0x2e, 0x62c, 0x2e, 0x642, 0x2e, 0x200f, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f, 0x62f, 0x2e,
-0x643, 0x2e, 0x200f, 0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e,
-0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53, 0x644,
-0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f, 0x564,
-0x580, 0x2e, 0x20b9, 0x6d, 0x61, 0x6e, 0x2e, 0x43c, 0x430, 0x43d, 0x2e, 0x20ac, 0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b,
+0x42, 0x72, 0x4b, 0x73, 0x68, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0x64, 0x65, 0x6e, 0x20ac,
+0x1265, 0x122d, 0x62c, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46,
+0x41, 0x641, 0x2e, 0x62c, 0x2e, 0x642, 0x2e, 0x200f, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f, 0x62f,
+0x2e, 0x643, 0x2e, 0x200f, 0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x200f, 0x62f,
+0x2e, 0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53,
+0x644, 0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f,
+0x564, 0x580, 0x2e, 0x20b9, 0x6d, 0x61, 0x6e, 0x2e, 0x43c, 0x430, 0x43d, 0x2e, 0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b,
0x440, 0x2e, 0x17db, 0xffe5, 0x4d, 0x4f, 0x50, 0x24, 0x4e, 0x54, 0x24, 0x6b, 0x6e, 0x4b, 0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x41,
0x66, 0x6c, 0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x45, 0x43, 0x24, 0x50, 0xa3, 0x44, 0x47, 0x48, 0x20b5, 0x41, 0x72, 0x4d, 0x4b,
0x52, 0x73, 0x20a6, 0x20b1, 0x57, 0x53, 0x24, 0x53, 0x52, 0x4c, 0x65, 0x45, 0x54, 0x53, 0x68, 0x54, 0x24, 0x55, 0x53, 0x68,
@@ -4504,7 +4507,7 @@ static const ushort currency_symbol_data[] = {
0x43, 0x46, 0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x52, 0x46, 0x43, 0x48, 0x46, 0x4c, 0x53, 0x44, 0x54, 0x46, 0x74, 0x52,
0x70, 0x20b8, 0x441, 0x43e, 0x43c, 0x20a9, 0x20ad, 0x4c, 0x73, 0x4b, 0x7a, 0x4c, 0x74, 0x434, 0x435, 0x43d, 0x52, 0x4d, 0x20ae, 0x928,
0x947, 0x930, 0x942, 0x60b, 0xfdfc, 0x7a, 0x142, 0x52, 0x24, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x440, 0x443, 0x431, 0x2e, 0x20b4,
-0x434, 0x438, 0x43d, 0x2e, 0x41a, 0x41c, 0x64, 0x69, 0x6e, 0x2e, 0xdbb, 0xdd4, 0x2e, 0x42, 0x73, 0x20a1, 0x51, 0x4c, 0x43, 0x24,
+0x434, 0x438, 0x43d, 0x2e, 0x64, 0x69, 0x6e, 0x2e, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x42, 0x73, 0x20a1, 0x51, 0x4c, 0x43, 0x24,
0x42, 0x2f, 0x2e, 0x20b2, 0x53, 0x2f, 0x2e, 0x42, 0x73, 0x2e, 0x52, 0x73, 0x2e, 0xe3f, 0xa5, 0x20ba, 0x441, 0x45e, 0x43c, 0x73,
0x6f, 0x2bb, 0x6d, 0x20ab
};
@@ -4514,360 +4517,360 @@ static const ushort currency_display_name_data[] = {
0x72, 0x72, 0x69, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x69, 0x64, 0x2d, 0x41, 0x66, 0x72, 0x69,
0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61,
0x6d, 0x69, 0x62, 0x69, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265,
-0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a,
-0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627,
-0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
-0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626,
-0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
-0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646,
-0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a,
-0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
-0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641,
-0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a,
-0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20,
-0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641,
-0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20,
-0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631,
-0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643,
-0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20,
-0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631,
-0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643,
-0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b,
-0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628,
-0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643,
-0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b,
-0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623,
-0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646,
-0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631,
-0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627,
-0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627,
-0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f,
-0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627,
-0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20,
-0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625,
-0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633,
-0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631,
-0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627,
-0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626,
-0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a,
-0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631,
-0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
-0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648,
-0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
-0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648,
-0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629,
-0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b,
-0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646,
-0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629,
-0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628,
+0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265,
+0x122d, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee,
+0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
+0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631,
+0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a,
+0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
+0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b,
+0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628,
+0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d,
+0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x641, 0x631,
+0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642,
+0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623,
+0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631,
+0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642,
+0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646,
+0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631,
+0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645,
+0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646,
+0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631,
+0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641,
+0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648,
+0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20,
+0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641,
+0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a,
+0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643,
+0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a,
+0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641,
+0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631,
+0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
+0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a,
+0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642,
+0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
+0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20,
+0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c,
+0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f,
+0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a,
+0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f,
+0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b,
+0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f,
+0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f,
+0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a,
+0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
+0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627,
+0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20,
+0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
+0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628,
0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644,
0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x623, 0x648, 0x642,
-0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645,
-0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a,
-0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629,
-0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642,
-0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645,
-0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b,
+0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
+0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627,
+0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b,
+0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a,
+0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648,
+0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627,
+0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b,
0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628,
0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a,
0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20,
-0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631,
0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a,
0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627,
-0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637,
-0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637,
-0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637,
-0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639,
-0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20,
+0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20,
0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631,
-0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a,
+0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a,
0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627,
0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648,
0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20,
-0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
-0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627,
-0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
-0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a,
-0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648,
+0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x62c, 0x646,
+0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646,
+0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633,
+0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646,
+0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646,
+0x64a, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648,
0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20,
0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631,
-0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f,
+0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x62f,
0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a,
0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646,
0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a,
-0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631,
-0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631,
-0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647,
-0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627,
-0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b,
-0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x3b, 0x3b, 0x540, 0x561,
-0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63,
-0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62,
-0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac, 0x9be, 0x982,
-0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ad, 0x9be,
-0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf51, 0xf44, 0xf74,
-0xf63, 0xf0b, 0xf40, 0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x431, 0x44a,
-0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430,
-0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x20, 0x1000, 0x103b, 0x1015,
-0x103a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443,
-0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x179a, 0x17c0, 0x179b, 0x20, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb,
-0x1787, 0x17b6, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
-0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x4eba, 0x6c11, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f,
-0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x95e8, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0,
-0x5761, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0,
-0x81fa, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75,
-0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68,
-0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x65, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b,
-0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75,
-0x6e, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72,
-0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61,
-0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d,
-0x61, 0x72, 0x6b, 0x65, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20,
-0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69,
-0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e,
-0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73,
-0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xfd, 0x63, 0x68, 0x20, 0x6b,
-0x6f, 0x72, 0x75, 0x6e, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x44, 0x61,
-0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x65, 0x20,
-0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b,
-0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72,
-0x69, 0x6e, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e,
-0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e,
-0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61,
-0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61,
-0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c,
-0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e,
-0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x53, 0x75,
-0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x61, 0x73,
-0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20,
-0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61,
-0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61,
-0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x6c, 0x69,
-0x7a, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x73, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42,
-0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x6f, 0x74, 0x73,
-0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x50, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61,
-0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20,
-0x70, 0x75, 0x6c, 0x61, 0x73, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43,
-0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b,
-0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x43, 0x61, 0x6e, 0x61,
-0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61,
-0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e,
-0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61,
-0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x79,
-0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61,
-0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64,
-0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42,
-0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61,
-0x6e, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61,
-0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61,
-0x73, 0x69, 0x73, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x47,
-0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e,
-0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72,
-0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f,
-0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75,
-0x6e, 0x64, 0x73, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
-0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x48, 0x6f,
-0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x48, 0x6f,
-0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x6e, 0x64, 0x69,
-0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70,
-0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b,
-0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4a, 0x61, 0x6d,
-0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61,
-0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20,
-0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
-0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c,
-0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20,
-0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20,
-0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c,
-0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61,
-0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69,
-0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20,
-0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b,
-0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70,
-0x65, 0x65, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b,
-0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b,
-0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d,
-0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69,
-0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61,
-0x6c, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61,
-0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a,
-0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72,
-0x69, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20,
-0x6e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61,
-0x69, 0x72, 0x61, 0x73, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65,
-0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b,
-0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61,
-0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61,
-0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20,
-0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75,
-0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x50, 0x68, 0x69,
-0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c,
-0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20,
-0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b,
-0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c,
-0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
-0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c,
-0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c,
-0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61,
-0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69,
-0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b,
-0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69,
-0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69,
-0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f,
-0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
-0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61,
-0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65,
-0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65,
-0x6e, 0x69, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e,
-0x67, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e,
-0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c,
-0x69, 0x6e, 0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b,
-0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x54,
-0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64,
-0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
-0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67,
-0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64,
-0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x55, 0x67,
-0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67,
-0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x56, 0x61, 0x6e, 0x75,
-0x61, 0x74, 0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61,
-0x74, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x73, 0x3b,
-0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62,
-0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61,
-0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61,
-0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75,
-0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74,
-0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x65, 0x75,
-0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x74, 0x3b, 0x64, 0x6f,
-0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3,
-0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b,
-0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61,
-0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73,
-0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41,
-0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20,
-0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46,
-0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75,
-0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61,
-0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61,
-0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63,
-0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72,
-0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69,
-0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b,
-0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61,
-0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
-0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9,
-0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x73, 0x3b, 0x67, 0x6f, 0x75,
-0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64,
-0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64,
-0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79,
-0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61,
-0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x73, 0x20, 0x6d, 0x61,
-0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72,
-0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75,
-0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x73,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70,
-0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x72,
-0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d,
-0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x73,
-0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61,
-0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69,
-0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73,
-0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
-0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68,
-0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x73,
-0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75,
-0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b,
-0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x73, 0x3b, 0x6c, 0x69, 0x76,
-0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73,
-0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x73, 0x20, 0x73, 0x79,
-0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69,
-0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
-0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x76,
-0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20,
-0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x73, 0x20, 0x76,
-0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x73, 0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61,
-0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75,
-0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20,
-0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72,
-0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20,
-0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46,
-0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20,
-0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x395, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x64, 0x61, 0x6e, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f,
-0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72,
-0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f,
-0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xac0, 0xaaf, 0xabe, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x75,
-0x257, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x66, 0x61, 0x20, 0x6e, 0x61, 0x20, 0x41, 0x66, 0x69, 0x72, 0x6b, 0x61, 0x20, 0x54,
-0x61, 0x20, 0x59, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5e9, 0x5f4, 0x5d7, 0x3b, 0x3b, 0x5e9,
-0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9,
-0x5d9, 0x5dd, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9,
-0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x92f, 0x93e,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xcd, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61,
-0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed,
-0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x52, 0x75, 0x70, 0x69,
-0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45,
-0x75, 0x72, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645,
+0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a,
+0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20,
+0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a,
+0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625,
+0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x540, 0x561, 0x575,
+0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576,
+0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x3b, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580,
+0x561, 0x574, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e,
+0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be,
+0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa,
+0x9bf, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf51, 0xf44, 0xf74, 0xf63, 0xf0b, 0xf40, 0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440,
+0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b,
+0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430,
+0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x20, 0x1000, 0x103b, 0x1015, 0x103a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x431,
+0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x179a, 0x17c0, 0x179b, 0x20, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b,
+0x4eba, 0x6c11, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3,
+0x95e8, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x81fa, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74,
+0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b,
+0x75, 0x6e, 0x65, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x68,
+0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72,
+0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65,
+0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76,
+0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x6b, 0x6f, 0x6e, 0x76,
+0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x6b, 0x6f,
+0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b,
+0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20,
+0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79,
+0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xfd, 0x63, 0x68, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x3b, 0x44, 0x61, 0x6e, 0x73,
+0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65,
+0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x75,
+0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x41, 0x72, 0x75,
+0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61,
+0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61,
+0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e,
+0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64,
+0x65, 0x6e, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c,
+0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65,
+0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73,
+0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65,
+0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69,
+0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74,
+0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x41,
+0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41, 0x75,
+0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41,
+0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61,
+0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d,
+0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69,
+0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e,
+0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42,
+0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64,
+0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x50, 0x75, 0x6c,
+0x61, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x3b,
+0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x73, 0x3b, 0x43, 0x46, 0x41,
+0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x73, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
+0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61,
+0x72, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e,
+0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x72,
+0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
+0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f,
+0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b,
+0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47,
+0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x73, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61,
+0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63,
+0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69,
+0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47,
+0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69,
+0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e,
+0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65,
+0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65,
+0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67,
+0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b,
+0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64,
+0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20,
+0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c,
+0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x73, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b,
+0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75,
+0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75,
+0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53,
+0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69,
+0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72,
+0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69,
+0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20,
+0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69,
+0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61,
+0x72, 0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61,
+0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b,
+0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x4d, 0x61,
+0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69,
+0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74,
+0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20,
+0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c,
+0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x69, 0x72, 0x61,
+0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x73, 0x3b, 0x50, 0x61, 0x6b, 0x69,
+0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61,
+0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e,
+0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47,
+0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e,
+0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x50,
+0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e,
+0x61, 0x3b, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70,
+0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65,
+0x73, 0x6f, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x53, 0x61, 0x6d,
+0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74,
+0x61, 0x6c, 0x61, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52, 0x75, 0x70, 0x65,
+0x65, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65,
+0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65,
+0x65, 0x73, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4c, 0x65,
+0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20,
+0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e,
+0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65,
+0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e,
+0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49,
+0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x6c,
+0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73,
+0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x53, 0x77,
+0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x61,
+0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e,
+0x69, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e,
+0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a,
+0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67,
+0x61, 0x6e, 0x20, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70,
+0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb,
+0x61, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f,
+0x62, 0x61, 0x67, 0x6f, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61,
+0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61,
+0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53,
+0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
+0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
+0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b,
+0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e,
+0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b,
+0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73,
+0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e,
+0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f,
+0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73,
+0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
+0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61,
+0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6e,
+0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67,
+0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65,
+0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e,
+0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b,
+0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b,
+0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29,
+0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x73, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46,
+0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43,
+0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e,
+0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69,
+0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69,
+0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f,
+0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f,
+0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75,
+0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69,
+0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74,
+0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x50, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x67,
+0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x73, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69,
+0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e,
+0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65,
+0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65,
+0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x6f,
+0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
+0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b,
+0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e,
+0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65,
+0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65,
+0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69,
+0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63,
+0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e,
+0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x73, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e,
+0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x73, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64,
+0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69,
+0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x3b, 0x3b,
+0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
+0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20,
+0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x73, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e,
+0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b,
+0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x73, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64,
+0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72,
+0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20,
+0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61,
+0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e,
+0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x73, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x73,
+0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x73, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
+0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b,
+0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x3b,
+0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x395,
+0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x64, 0x61,
+0x6e, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x64, 0x61,
+0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x64,
+0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0xaad, 0xabe, 0xab0,
+0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xac0, 0xaaf, 0xabe, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x69,
+0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x75, 0x257, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x66, 0x61, 0x20,
+0x6e, 0x61, 0x20, 0x41, 0x66, 0x69, 0x72, 0x6b, 0x61, 0x20, 0x54, 0x61, 0x20, 0x59, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5e9, 0x5f4, 0x5d7, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9,
+0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd,
+0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d,
+0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61,
+0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xcd, 0x73,
+0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b,
+0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20,
+0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65,
+0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x66,
0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
0x61, 0x6e, 0x63, 0x68, 0x69, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x69, 0x3b, 0x65e5, 0x672c, 0x5186, 0x3b, 0x3b,
@@ -4979,32 +4982,32 @@ static const ushort currency_display_name_data[] = {
0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441,
0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445,
0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430,
-0x440, 0x430, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x41c, 0x430, 0x440,
-0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e,
-0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20,
-0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446,
-0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b,
-0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x65, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435,
-0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x430,
-0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441,
-0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d,
-0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415,
-0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430,
-0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x4b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20,
+0x440, 0x430, 0x3b, 0x4b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72,
+0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f,
+0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20,
0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63,
-0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
-0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68,
-0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69,
-0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f,
-0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65,
-0x72, 0x74, 0x61, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x62, 0x6f, 0x73,
-0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20,
-0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b,
-0x61, 0x3b, 0x45, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65,
-0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61,
-0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70,
-0x73, 0x6b, 0x61, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64,
-0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61,
+0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
+0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65,
+0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x61,
+0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73,
+0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e,
+0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x45,
+0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x61,
+0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b,
+0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x61,
+0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61,
+0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x41a, 0x43e,
+0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x41c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431,
+0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430,
+0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430,
+0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430,
+0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430,
+0x440, 0x43a, 0x65, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e,
+0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x430, 0x431, 0x438, 0x43b, 0x43d, 0x438,
+0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435,
+0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438,
+0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415, 0x432, 0x440, 0x43e, 0x3b, 0x3b,
+0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430,
0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b, 0x421, 0x43e,
0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72, 0x61, 0x20,
0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xdbd, 0xd82, 0xd9a,
@@ -5211,254 +5214,255 @@ static const ushort endonyms_data[] = {
0x69, 0x79, 0x61, 0x61, 0x51, 0x61, 0x66, 0x61, 0x72, 0x4f, 0x74, 0x6f, 0x62, 0x62, 0x69, 0x61, 0x59, 0x61, 0x62, 0x75,
0x75, 0x74, 0x69, 0x45, 0x72, 0x65, 0x74, 0x72, 0x69, 0x61, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x53,
0x75, 0x69, 0x64, 0x2d, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0xeb, 0x73, 0x68, 0x71,
-0x69, 0x70, 0x53, 0x68, 0x71, 0x69, 0x70, 0xeb, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x69, 0x12a0,
-0x121b, 0x122d, 0x129b, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x645, 0x635, 0x631, 0x627, 0x644,
-0x62c, 0x632, 0x627, 0x626, 0x631, 0x627, 0x644, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x62a, 0x634, 0x627, 0x62f, 0x62c, 0x632, 0x631, 0x20,
-0x627, 0x644, 0x642, 0x645, 0x631, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x627, 0x627, 0x644,
-0x639, 0x631, 0x627, 0x642, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x627, 0x644, 0x623, 0x631, 0x62f, 0x646, 0x627, 0x644, 0x643,
-0x648, 0x64a, 0x62a, 0x644, 0x628, 0x646, 0x627, 0x646, 0x644, 0x64a, 0x628, 0x64a, 0x627, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646,
-0x64a, 0x627, 0x627, 0x644, 0x645, 0x63a, 0x631, 0x628, 0x639, 0x64f, 0x645, 0x627, 0x646, 0x641, 0x644, 0x633, 0x637, 0x64a, 0x646, 0x642,
-0x637, 0x631, 0x627, 0x644, 0x645, 0x645, 0x644, 0x643, 0x629, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644,
-0x633, 0x639, 0x648, 0x62f, 0x64a, 0x629, 0x627, 0x644, 0x635, 0x648, 0x645, 0x627, 0x644, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646,
-0x633, 0x648, 0x631, 0x64a, 0x627, 0x62a, 0x648, 0x646, 0x633, 0x627, 0x644, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x20, 0x627, 0x644,
-0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x645, 0x62a, 0x62d, 0x62f, 0x629, 0x627, 0x644, 0x635, 0x62d, 0x631, 0x627, 0x621,
-0x20, 0x627, 0x644, 0x63a, 0x631, 0x628, 0x64a, 0x629, 0x627, 0x644, 0x64a, 0x645, 0x646, 0x570, 0x561, 0x575, 0x565, 0x580, 0x565, 0x576,
-0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576, 0x985, 0x9b8, 0x9ae, 0x9c0, 0x9af, 0x9bc, 0x9be, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x61,
-0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x63, 0x61, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61,
-0x6e, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x65, 0x75, 0x73, 0x6b, 0x61, 0x72, 0x61, 0x45, 0x73,
-0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad,
-0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41, 0xf60, 0xf56, 0xfb2, 0xf74, 0xf42, 0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f,
-0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b,
-0x433, 0x430, 0x440, 0x438, 0x44f, 0x1017, 0x1019, 0x102c, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443,
-0x441, 0x43a, 0x430, 0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c, 0x1781, 0x17d2, 0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2,
-0x1796, 0x17bb, 0x1787, 0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73, 0x70, 0x61, 0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64,
-0x6f, 0x72, 0x72, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d, 0x56fd, 0x9999, 0x6e2f, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d,
-0x56fd, 0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761, 0x7e41, 0x9ad4, 0x4e2d, 0x6587, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171,
-0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225,
-0x884c, 0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x48, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b,
-0x61, 0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61,
-0x10d, 0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x72, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69,
-0x6b, 0x61, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c,
-0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x75, 0x62, 0x61, 0x56, 0x6c,
-0x61, 0x61, 0x6d, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0xeb, 0x43, 0x75, 0x72, 0x61, 0xe7, 0x61, 0x6f, 0x53, 0x75, 0x72,
-0x69, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x65, 0x6e, 0x55, 0x2e, 0x53,
-0x2e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, 0x74, 0x61, 0x74,
-0x65, 0x73, 0xd801, 0xdc00, 0xd801, 0xdc4d, 0xd801, 0xdc4a, 0xd801, 0xdc2e, 0xd801, 0xdc47, 0xd801, 0xdc0f, 0xd801, 0xdc2d, 0xd801, 0xdc4c, 0xd801, 0xdc34,
-0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801, 0xdc3c, 0x20, 0xd801, 0xdc1d, 0xd801, 0xdc3b, 0xd801, 0xdc29, 0xd801, 0xdc3b, 0xd801, 0xdc45, 0x45, 0x6e, 0x67,
-0x6c, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e,
-0x74, 0x69, 0x67, 0x75, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x42, 0x61, 0x72, 0x62, 0x75, 0x64, 0x61, 0x41, 0x75, 0x73,
-0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x75, 0x73, 0x74, 0x72,
-0x61, 0x6c, 0x69, 0x61, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x61, 0x73, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x6f, 0x73, 0x42,
-0x65, 0x6c, 0x67, 0x69, 0x75, 0x6d, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x42,
-0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64,
-0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x43, 0x61, 0x79,
-0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x46,
-0x69, 0x6a, 0x69, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x47, 0x68, 0x61,
-0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x47, 0x75,
-0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x53, 0x41,
-0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x49, 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x4a,
-0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69, 0x72, 0x69, 0x62, 0x61, 0x74, 0x69, 0x4c,
-0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73,
-0x63, 0x61, 0x72, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x4d, 0x61, 0x6c, 0x74, 0x61, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61,
-0x6c, 0x6c, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x4d,
-0x69, 0x63, 0x72, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x4e, 0x65, 0x77, 0x20,
-0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x65,
-0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x61, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x50, 0x61,
-0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77,
-0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x73, 0x50, 0x75,
-0x65, 0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x4b, 0x69, 0x74, 0x74, 0x73,
-0x20, 0x61, 0x6e, 0x64, 0x20, 0x4e, 0x65, 0x76, 0x69, 0x73, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x4c, 0x75, 0x63, 0x69,
-0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74,
-0x68, 0x65, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x53, 0x65,
-0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65,
-0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c,
-0x61, 0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x53, 0x77, 0x61, 0x7a,
-0x69, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72,
-0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x54, 0x75, 0x72,
-0x6b, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
-0x73, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69,
-0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e,
-0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e,
-0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73,
-0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x5a, 0x69, 0x6d, 0x62, 0x61, 0x62, 0x77, 0x65, 0x49,
-0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73, 0x65, 0x79, 0x53, 0x6f, 0x75, 0x74,
-0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65, 0x73, 0x74, 0x69, 0x66, 0xf8, 0x72,
-0x6f, 0x79, 0x73, 0x6b, 0x74, 0x46, 0xf8, 0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75, 0x6f, 0x6d, 0x69, 0x53, 0x75, 0x6f,
-0x6d, 0x69, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x67, 0xe9,
-0x72, 0x69, 0x65, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e, 0x69, 0x6e, 0x42, 0x75, 0x72, 0x6b,
-0x69, 0x6e, 0x61, 0x20, 0x46, 0x61, 0x73, 0x6f, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x43, 0x61, 0x6d, 0x65, 0x72,
-0x6f, 0x75, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e,
-0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x66, 0x72, 0x69,
-0x63, 0x61, 0x69, 0x6e, 0x65, 0x54, 0x63, 0x68, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6f, 0x72, 0x65, 0x73, 0x52, 0xe9, 0x70,
-0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0xe9, 0x6d, 0x6f, 0x63, 0x72, 0x61, 0x74, 0x69, 0x71, 0x75, 0x65,
-0x20, 0x64, 0x75, 0x20, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a,
-0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x43, 0xf4, 0x74, 0x65, 0x20, 0x64, 0x2019, 0x49, 0x76, 0x6f, 0x69, 0x72, 0x65, 0x44,
-0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x20, 0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f,
-0x72, 0x69, 0x61, 0x6c, 0x65, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73,
-0x65, 0x50, 0x6f, 0x6c, 0x79, 0x6e, 0xe9, 0x73, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65,
-0x47, 0x61, 0x62, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9,
-0x65, 0x48, 0x61, 0xef, 0x74, 0x69, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75, 0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69,
-0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65,
-0x4d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f,
-0x4d, 0x61, 0x72, 0x6f, 0x63, 0x4e, 0x6f, 0x75, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x2d, 0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f,
-0x6e, 0x69, 0x65, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x52, 0x77, 0x61, 0x6e, 0x64,
-0x61, 0x53, 0xe9, 0x6e, 0xe9, 0x67, 0x61, 0x6c, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x73, 0x75, 0x69,
-0x73, 0x73, 0x65, 0x53, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x79, 0x72, 0x69, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75,
-0x6e, 0x69, 0x73, 0x69, 0x65, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x42, 0x61, 0x72, 0x74, 0x68, 0xe9, 0x6c, 0xe9, 0x6d,
-0x79, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x20, 0x5b, 0x70, 0x61, 0x72, 0x74, 0x69,
-0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x5d, 0x47, 0xe0, 0x69, 0x64, 0x68, 0x6c, 0x69, 0x67,
-0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68, 0x61, 0x63, 0x68, 0x64, 0x20, 0x41, 0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68,
-0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da,
-0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5, 0x10d4, 0x10da, 0x10dd, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x44, 0x65,
-0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0xd6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x69,
-0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0xd6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65,
-0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63, 0x68, 0x74, 0x65, 0x6e, 0x73, 0x74,
-0x65, 0x69, 0x6e, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65,
-0x72, 0x20, 0x48, 0x6f, 0x63, 0x68, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a,
-0x395, 0x3bb, 0x3bb, 0x3b7, 0x3bd, 0x3b9, 0x3ba, 0x3ac, 0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1, 0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2,
-0x6b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74,
-0x20, 0x4e, 0x75, 0x6e, 0x61, 0x61, 0x74, 0xa97, 0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0, 0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61,
-0x75, 0x73, 0x61, 0x4e, 0x61, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e, 0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72,
-0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d, 0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924,
-0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72, 0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73,
-0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x49,
-0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x69, 0x6e, 0x74,
-0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x75, 0x61, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x47, 0x61, 0x65, 0x69, 0x6c,
-0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x61,
-0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x61, 0x65e5, 0x672c,
-0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672, 0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646,
-0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442, 0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437,
-0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x41a, 0x44b, 0x440,
-0x433, 0x44b, 0x437, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c, 0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d,
-0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e,
-0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2, 0xea7, 0xeaa, 0x2e, 0xe9b, 0x2e, 0xe9b, 0x20, 0xea5,
-0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e,
-0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61,
-0x74, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52,
-0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72, 0xed, 0x6b, 0x61, 0x20, 0x79, 0x61,
-0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x69, 0x173, 0x4c, 0x69,
-0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434,
-0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73,
-0x69, 0x6b, 0x61, 0x72, 0x61, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, 0x65, 0x6c, 0x61, 0x79, 0x75, 0x4d, 0x61,
-0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72,
-0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d, 0x61, 0x6c, 0x74, 0x69, 0x92e, 0x930,
-0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x928, 0x947, 0x92a, 0x93e, 0x932,
-0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, 0x6b, 0x6d, 0xe5, 0x6c, 0x4e, 0x6f,
-0x72, 0x67, 0x65, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a, 0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627,
-0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f,
-0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20,
-0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x70, 0x6f, 0x72, 0x74, 0x75,
-0x67, 0x75, 0xea, 0x73, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f, 0x20, 0x56, 0x65, 0x72, 0x64, 0x65,
-0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x2d, 0x42, 0x69, 0x73,
-0x73, 0x61, 0x75, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20, 0x64, 0x61, 0x20, 0x43, 0x68, 0x69,
-0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea,
-0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f,
-0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0xa2a, 0xa70, 0xa1c, 0xa3e,
-0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x67e, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x72, 0x75, 0x6d,
-0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f,
-0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f,
-0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445,
-0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e, 0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423,
-0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64, 0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73,
-0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421,
-0x440, 0x431, 0x438, 0x458, 0x430, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x411, 0x43e, 0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, 0x425,
-0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d, 0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, 0x53,
-0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e, 0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61,
-0x438, 0x440, 0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441,
-0x435, 0x53, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x53, 0x65, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, 0x53,
-0x68, 0x6f, 0x6e, 0x61, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0,
-0x53, 0x69, 0x73, 0x77, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f,
-0x76, 0x65, 0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f,
-0x76, 0x65, 0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61,
-0x6c, 0x69, 0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x4b,
-0x69, 0x69, 0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70,
-0x61, 0xf1, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42,
-0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43,
-0x6f, 0x73, 0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69,
-0x63, 0x61, 0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72,
-0x45, 0x6c, 0x20, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63,
-0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e,
-0x64, 0x75, 0x72, 0x61, 0x73, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61,
-0x50, 0x61, 0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x50, 0x65, 0x72, 0xfa, 0x46, 0x69,
-0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f,
-0x73, 0x55, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x49, 0x73, 0x6c,
-0x61, 0x73, 0x20, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c,
-0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f,
-0x61, 0x6d, 0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c,
-0x6c, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76,
-0x65, 0x72, 0x69, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x422, 0x43e, 0x4b7,
-0x438, 0x43a, 0x4e3, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8,
-0xbcd, 0xba4, 0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa,
-0xbc2, 0xbb0, 0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0x20,
-0xc26, 0xc47, 0xc36, 0xc02, 0xe44, 0xe17, 0xe22, 0xf54, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53,
-0xf42, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20,
-0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x58, 0x69, 0x74, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72,
-0x6b, 0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x47, 0xfc, 0x6e, 0x65, 0x79, 0x20, 0x4b, 0x131, 0x62, 0x72,
-0x131, 0x73, 0x20, 0x52, 0x75, 0x6d, 0x20, 0x4b, 0x65, 0x73, 0x69, 0x6d, 0x69, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441,
-0x44c, 0x43a, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, 0x631, 0x62f, 0x648, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627,
-0x646, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e,
-0x43d, 0x627, 0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x6f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x63, 0x68, 0x61, 0x4f, 0x2bb, 0x7a, 0x62,
-0x65, 0x6b, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7,
-0x74, 0x20, 0x4e, 0x61, 0x6d, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67, 0x79, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61,
-0x73, 0x20, 0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x69, 0x73, 0x69, 0x58, 0x68, 0x6f, 0x73, 0x61, 0xc8, 0x64, 0xe8, 0x20,
-0x59, 0x6f, 0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a,
-0xed, 0x72, 0xed, 0xe0, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, 0x69, 0x6d,
-0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67,
-0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c,
-0x67, 0x52, 0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x6b, 0x65, 0x72, 0x6e, 0x65,
-0x77, 0x65, 0x6b, 0x41, 0x6b, 0x61, 0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67,
-0x62, 0x6f, 0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x1265, 0x120a, 0x1295, 0x1275, 0x130d, 0x1228, 0x66, 0x75, 0x72, 0x6c, 0x61,
-0x6e, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x65, 0x54, 0x73, 0x68, 0x69, 0x76, 0x65, 0x6e, 0x1e13, 0x61, 0x65, 0x28b, 0x65, 0x67,
-0x62, 0x65, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e,
-0x75, 0x74, 0x6f, 0x6d, 0x65, 0x12c8, 0x120b, 0x12ed, 0x1273, 0x1271, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77,
-0x61, 0x69, 0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20,
-0x2bb, 0x49, 0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73,
-0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77,
-0x69, 0x69, 0x7a, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x69, 0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65, 0x6c, 0x65, 0x53, 0x65,
-0x73, 0x6f, 0x74, 0x68, 0x6f, 0x20, 0x73, 0x61, 0x20, 0x4c, 0x65, 0x62, 0x6f, 0x61, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73,
-0xe1, 0x6d, 0x65, 0x67, 0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61,
-0x45, 0x6b, 0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61,
-0x72, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d,
-0x70, 0x75, 0x72, 0x73, 0x65, 0x6e, 0x61, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30,
-0x2d63, 0x2d49, 0x2d56, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x74, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x67, 0x68, 0x74, 0x6c,
-0x6d, 0x263, 0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79,
-0x65, 0x72, 0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75,
-0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61,
-0x6e, 0x61, 0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13a0, 0x13b9, 0x13f0, 0x13df, 0x6b, 0x72,
-0x65, 0x6f, 0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69,
-0x6d, 0x61, 0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73,
-0x61, 0x6e, 0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63,
-0x68, 0x69, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b,
-0x61, 0x62, 0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e,
-0x6a, 0x69, 0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b,
-0x68, 0x6f, 0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61,
-0x63, 0x68, 0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61,
-0x6e, 0x64, 0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61,
-0x4c, 0x75, 0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69,
-0x61, 0x4b, 0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69,
-0x69, 0x6e, 0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f,
-0x52, 0x75, 0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b,
-0x4b, 0x6f, 0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61,
-0x6d, 0x62, 0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75,
-0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x41, 0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d,
-0xe0, 0x6c, 0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72,
-0x6d, 0x61, 0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f,
-0x6c, 0x61, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72,
-0xfa, 0x6e, 0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55,
-0x6d, 0x6f, 0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72,
-0x75, 0x14b, 0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20,
-0x4e, 0x61, 0x74, 0x68, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x49, 0x73,
-0x68, 0x69, 0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x73, 0x77,
-0x61, 0x68, 0x69, 0x6c, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x4a, 0x61, 0x6d, 0x68, 0x75, 0x72,
-0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, 0x61, 0x20, 0x79, 0x61,
-0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559,
-0xa524, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73,
-0x65, 0x72, 0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa,
-0x6e, 0x61, 0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c,
-0xfb, 0x6e, 0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61,
-0x6d, 0x61, 0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254,
-0x6e, 0x4b, 0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d
+0x69, 0x70, 0x53, 0x68, 0x71, 0x69, 0x70, 0xeb, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x69, 0x4b,
+0x6f, 0x73, 0x6f, 0x76, 0xeb, 0x12a0, 0x121b, 0x122d, 0x129b, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a,
+0x629, 0x645, 0x635, 0x631, 0x627, 0x644, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x627, 0x644, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x62a, 0x634,
+0x627, 0x62f, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x623, 0x631, 0x64a,
+0x62a, 0x631, 0x64a, 0x627, 0x627, 0x644, 0x639, 0x631, 0x627, 0x642, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x627, 0x644, 0x623,
+0x631, 0x62f, 0x646, 0x627, 0x644, 0x643, 0x648, 0x64a, 0x62a, 0x644, 0x628, 0x646, 0x627, 0x646, 0x644, 0x64a, 0x628, 0x64a, 0x627, 0x645,
+0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x627, 0x627, 0x644, 0x645, 0x63a, 0x631, 0x628, 0x639, 0x64f, 0x645, 0x627, 0x646, 0x641,
+0x644, 0x633, 0x637, 0x64a, 0x646, 0x642, 0x637, 0x631, 0x627, 0x644, 0x645, 0x645, 0x644, 0x643, 0x629, 0x20, 0x627, 0x644, 0x639, 0x631,
+0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x629, 0x627, 0x644, 0x635, 0x648, 0x645, 0x627, 0x644, 0x627,
+0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x633, 0x648, 0x631, 0x64a, 0x627, 0x62a, 0x648, 0x646, 0x633, 0x627, 0x644, 0x625, 0x645, 0x627,
+0x631, 0x627, 0x62a, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x645, 0x62a, 0x62d, 0x62f, 0x629, 0x627,
+0x644, 0x635, 0x62d, 0x631, 0x627, 0x621, 0x20, 0x627, 0x644, 0x63a, 0x631, 0x628, 0x64a, 0x629, 0x627, 0x644, 0x64a, 0x645, 0x646, 0x570,
+0x561, 0x575, 0x565, 0x580, 0x565, 0x576, 0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576, 0x985, 0x9b8, 0x9ae, 0x9c0, 0x9af, 0x9bc,
+0x9be, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x61, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x63, 0x61, 0x41, 0x7a, 0x259,
+0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x65, 0x75, 0x73,
+0x6b, 0x61, 0x72, 0x61, 0x45, 0x73, 0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9ac, 0x9be, 0x982,
+0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41, 0xf60, 0xf56, 0xfb2, 0xf74, 0xf42,
+0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f, 0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440,
+0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x438, 0x44f, 0x1017, 0x1019, 0x102c, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c,
+0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x430, 0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c, 0x1781, 0x17d2,
+0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73, 0x70, 0x61,
+0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d, 0x56fd, 0x9999, 0x6e2f,
+0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d, 0x56fd, 0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761, 0x7e41, 0x9ad4, 0x4e2d,
+0x6587, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171,
+0x548c, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x48,
+0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48, 0x65, 0x72, 0x63, 0x65,
+0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61, 0x10d, 0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x72,
+0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b, 0x61, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b,
+0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x41,
+0x72, 0x75, 0x62, 0x61, 0x56, 0x6c, 0x61, 0x61, 0x6d, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0xeb, 0x43, 0x75, 0x72, 0x61,
+0xe7, 0x61, 0x6f, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x61, 0x72,
+0x74, 0x65, 0x6e, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65,
+0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0xd801, 0xdc00, 0xd801, 0xdc4d, 0xd801, 0xdc4a, 0xd801, 0xdc2e, 0xd801, 0xdc47, 0xd801, 0xdc0f,
+0xd801, 0xdc2d, 0xd801, 0xdc4c, 0xd801, 0xdc34, 0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801, 0xdc3c, 0x20, 0xd801, 0xdc1d, 0xd801, 0xdc3b, 0xd801, 0xdc29, 0xd801,
+0xdc3b, 0xd801, 0xdc45, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x53,
+0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x42, 0x61, 0x72, 0x62,
+0x75, 0x64, 0x61, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
+0x68, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x61, 0x73, 0x42, 0x61, 0x72,
+0x62, 0x61, 0x64, 0x6f, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x75, 0x6d, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65,
+0x72, 0x6d, 0x75, 0x64, 0x61, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6f,
+0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x43, 0x61, 0x6e,
+0x61, 0x64, 0x61, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x44, 0x6f, 0x6d,
+0x69, 0x6e, 0x69, 0x63, 0x61, 0x46, 0x69, 0x6a, 0x69, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d,
+0x62, 0x69, 0x61, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x47, 0x72, 0x65,
+0x6e, 0x61, 0x64, 0x61, 0x47, 0x75, 0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b,
+0x6f, 0x6e, 0x67, 0x20, 0x53, 0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x49, 0x72,
+0x65, 0x6c, 0x61, 0x6e, 0x64, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69, 0x72,
+0x69, 0x62, 0x61, 0x74, 0x69, 0x4c, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x4d,
+0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x63, 0x61, 0x72, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x4d, 0x61, 0x6c, 0x74, 0x61,
+0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x75, 0x72,
+0x69, 0x74, 0x69, 0x75, 0x73, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62,
+0x69, 0x61, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61,
+0x4e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x61, 0x20, 0x49, 0x73, 0x6c,
+0x61, 0x6e, 0x64, 0x73, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x50, 0x61, 0x70,
+0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70,
+0x69, 0x6e, 0x65, 0x73, 0x50, 0x75, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x53, 0x61, 0x69, 0x6e, 0x74,
+0x20, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4e, 0x65, 0x76, 0x69, 0x73, 0x53, 0x61, 0x69, 0x6e,
+0x74, 0x20, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74,
+0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x53,
+0x61, 0x6d, 0x6f, 0x61, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61,
+0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x6c, 0x6f, 0x6d,
+0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69,
+0x63, 0x61, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x54,
+0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62,
+0x61, 0x67, 0x6f, 0x54, 0x75, 0x72, 0x6b, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20,
+0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
+0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, 0x64,
+0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x49, 0x73, 0x6c, 0x61,
+0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x56, 0x69,
+0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x56, 0x69, 0x72,
+0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x5a, 0x69, 0x6d,
+0x62, 0x61, 0x62, 0x77, 0x65, 0x49, 0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73,
+0x65, 0x79, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65,
+0x73, 0x74, 0x69, 0x66, 0xf8, 0x72, 0x6f, 0x79, 0x73, 0x6b, 0x74, 0x46, 0xf8, 0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75,
+0x6f, 0x6d, 0x69, 0x53, 0x75, 0x6f, 0x6d, 0x69, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e,
+0x63, 0x65, 0x41, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e,
+0x69, 0x6e, 0x42, 0x75, 0x72, 0x6b, 0x69, 0x6e, 0x61, 0x20, 0x46, 0x61, 0x73, 0x6f, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64,
+0x69, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x75, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x63, 0x61,
+0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63, 0x65, 0x6e,
+0x74, 0x72, 0x61, 0x66, 0x72, 0x69, 0x63, 0x61, 0x69, 0x6e, 0x65, 0x54, 0x63, 0x68, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6f,
+0x72, 0x65, 0x73, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0xe9, 0x6d, 0x6f, 0x63, 0x72,
+0x61, 0x74, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0x75, 0x20, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x43, 0x6f, 0x6e, 0x67, 0x6f,
+0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x43, 0xf4, 0x74, 0x65, 0x20, 0x64, 0x2019, 0x49,
+0x76, 0x6f, 0x69, 0x72, 0x65, 0x44, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x20,
+0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x65, 0x20, 0x66, 0x72,
+0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x50, 0x6f, 0x6c, 0x79, 0x6e, 0xe9, 0x73, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61,
+0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x47, 0x61, 0x62, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70,
+0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x48, 0x61, 0xef, 0x74, 0x69, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75,
+0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x75, 0x72,
+0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65,
+0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x4d, 0x61, 0x72, 0x6f, 0x63, 0x4e, 0x6f, 0x75, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x2d,
+0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f, 0x6e, 0x69, 0x65, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f,
+0x6e, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x53, 0xe9, 0x6e, 0xe9, 0x67, 0x61, 0x6c, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61,
+0x69, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x79, 0x72, 0x69, 0x65,
+0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x42, 0x61, 0x72,
+0x74, 0x68, 0xe9, 0x6c, 0xe9, 0x6d, 0x79, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x20,
+0x5b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x5d, 0x47, 0xe0,
+0x69, 0x64, 0x68, 0x6c, 0x69, 0x67, 0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68, 0x61, 0x63, 0x68, 0x64, 0x20, 0x41,
+0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61,
+0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5, 0x10d4, 0x10da, 0x10dd, 0x44, 0x65, 0x75,
+0x74, 0x73, 0x63, 0x68, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0xd6, 0x73, 0x74, 0x65, 0x72,
+0x72, 0x65, 0x69, 0x63, 0x68, 0x69, 0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0xd6,
+0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63,
+0x68, 0x74, 0x65, 0x6e, 0x73, 0x74, 0x65, 0x69, 0x6e, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x53, 0x63,
+0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x48, 0x6f, 0x63, 0x68, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x53,
+0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x395, 0x3bb, 0x3bb, 0x3b7, 0x3bd, 0x3b9, 0x3ba, 0x3ac, 0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1,
+0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2, 0x6b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c,
+0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74, 0x20, 0x4e, 0x75, 0x6e, 0x61, 0x61, 0x74, 0xa97, 0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0,
+0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61, 0x75, 0x73, 0x61, 0x4e, 0x61, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e,
+0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72, 0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d,
+0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72,
+0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x42, 0x61,
+0x68, 0x61, 0x73, 0x61, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65,
+0x73, 0x69, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x75, 0x61, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69,
+0x61, 0x47, 0x61, 0x65, 0x69, 0x6c, 0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f,
+0x49, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a,
+0x7a, 0x65, 0x72, 0x61, 0x65e5, 0x672c, 0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672,
+0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646, 0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442,
+0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61,
+0x6e, 0x64, 0x61, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c,
+0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d,
+0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2, 0xea7, 0xeaa,
+0x2e, 0xe9b, 0x2e, 0xe9b, 0x20, 0xea5, 0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76,
+0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x64,
+0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x41,
+0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72,
+0xed, 0x6b, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74,
+0x75, 0x76, 0x69, 0x173, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a,
+0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d,
+0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x69, 0x6b, 0x61, 0x72, 0x61, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, 0x65,
+0x6c, 0x61, 0x79, 0x75, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69,
+0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d,
+0x61, 0x6c, 0x74, 0x69, 0x92e, 0x930, 0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e,
+0x43b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f,
+0x6b, 0x6d, 0xe5, 0x6c, 0x4e, 0x6f, 0x72, 0x67, 0x65, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a,
+0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627,
+0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74,
+0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x42, 0x72, 0x61, 0x73, 0x69,
+0x6c, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f,
+0x20, 0x56, 0x65, 0x72, 0x64, 0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69,
+0x6e, 0xe9, 0x2d, 0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20,
+0x64, 0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f,
+0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75,
+0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69,
+0x70, 0x65, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x67e, 0x6a9, 0x633,
+0x62a, 0x627, 0x646, 0x72, 0x75, 0x6d, 0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f,
+0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f, 0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61,
+0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438,
+0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e,
+0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64,
+0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73, 0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x421,
+0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421, 0x440, 0x431, 0x438, 0x458, 0x430, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e,
+0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x411, 0x43e,
+0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, 0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d,
+0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, 0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f, 0x438, 0x440,
+0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441, 0x435, 0x53,
+0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x53, 0x65, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f,
+0x6e, 0x61, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0, 0x53, 0x69,
+0x73, 0x77, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
+0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
+0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69,
+0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x69,
+0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70, 0x61, 0xf1,
+0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42, 0x6f, 0x6c,
+0x69, 0x76, 0x69, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43, 0x6f, 0x73,
+0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69, 0x63, 0x61,
+0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72, 0x45, 0x6c,
+0x20, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, 0x75, 0x61,
+0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, 0x64, 0x75,
+0x72, 0x61, 0x73, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61,
+0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x50, 0x65, 0x72, 0xfa, 0x46, 0x69, 0x6c, 0x69,
+0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x55,
+0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x49, 0x73, 0x6c, 0x61, 0x73,
+0x20, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c, 0x61, 0x74,
+0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d,
+0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x61,
+0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76, 0x65, 0x72,
+0x69, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x422, 0x43e, 0x4b7, 0x438, 0x43a,
+0x4e3, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4,
+0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0,
+0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0x20, 0xc26, 0xc47,
+0xc36, 0xc02, 0xe44, 0xe17, 0xe22, 0xf54, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62,
+0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61,
+0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x58, 0x69, 0x74, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b, 0xe7,
+0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x47, 0xfc, 0x6e, 0x65, 0x79, 0x20, 0x4b, 0x131, 0x62, 0x72, 0x131, 0x73,
+0x20, 0x52, 0x75, 0x6d, 0x20, 0x4b, 0x65, 0x73, 0x69, 0x6d, 0x69, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a,
+0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, 0x631, 0x62f, 0x648, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x628,
+0x6be, 0x627, 0x631, 0x62a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x627,
+0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x6f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x63, 0x68, 0x61, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b,
+0x69, 0x73, 0x74, 0x6f, 0x6e, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7, 0x74, 0x20,
+0x4e, 0x61, 0x6d, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67, 0x79, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20,
+0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x69, 0x73, 0x69, 0x58, 0x68, 0x6f, 0x73, 0x61, 0xc8, 0x64, 0xe8, 0x20, 0x59, 0x6f,
+0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72,
+0xed, 0xe0, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, 0x69, 0x6d, 0x75, 0x20,
+0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67, 0x62, 0x6f,
+0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c, 0x67, 0x52,
+0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x77, 0x65,
+0x6b, 0x41, 0x6b, 0x61, 0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f,
+0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x1265, 0x120a, 0x1295, 0x1275, 0x130d, 0x1228, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e, 0x49,
+0x74, 0x61, 0x6c, 0x69, 0x65, 0x54, 0x73, 0x68, 0x69, 0x76, 0x65, 0x6e, 0x1e13, 0x61, 0x65, 0x28b, 0x65, 0x67, 0x62, 0x65,
+0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74,
+0x6f, 0x6d, 0x65, 0x12c8, 0x120b, 0x12ed, 0x1273, 0x1271, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77, 0x61, 0x69,
+0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20, 0x2bb, 0x49,
+0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x53, 0x63,
+0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69,
+0x7a, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x69, 0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x6f,
+0x74, 0x68, 0x6f, 0x20, 0x73, 0x61, 0x20, 0x4c, 0x65, 0x62, 0x6f, 0x61, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1, 0x6d,
+0x65, 0x67, 0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x45, 0x6b,
+0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61, 0x72, 0x53,
+0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75,
+0x72, 0x73, 0x65, 0x6e, 0x61, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49,
+0x2d56, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x74, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x6d, 0x263,
+0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79, 0x65, 0x72,
+0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75, 0x74, 0x61,
+0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61, 0x6e, 0x61,
+0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13a0, 0x13b9, 0x13f0, 0x13df, 0x6b, 0x72, 0x65, 0x6f,
+0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61,
+0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e,
+0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69,
+0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62,
+0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69,
+0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f,
+0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68,
+0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64,
+0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75,
+0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b,
+0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e,
+0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75,
+0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x4b, 0x6f,
+0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61, 0x6d, 0x62,
+0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75, 0x6e, 0x67,
+0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x41, 0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c,
+0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61,
+0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61,
+0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e,
+0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f,
+0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b,
+0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61,
+0x74, 0x68, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x49, 0x73, 0x68, 0x69,
+0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68,
+0x69, 0x6c, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x4a, 0x61, 0x6d, 0x68, 0x75, 0x72, 0x69, 0x20,
+0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b,
+0x6f, 0x6e, 0x67, 0x6f, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559, 0xa524, 0xa55e,
+0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73, 0x65, 0x72,
+0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa, 0x6e, 0x61,
+0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c, 0xfb, 0x6e,
+0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61, 0x6d, 0x61,
+0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254, 0x6e, 0x4b,
+0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d
};
static const char language_name_list[] =
@@ -6565,6 +6569,7 @@ static const char country_name_list[] =
"SouthSudan\0"
"Bonaire\0"
"SintMaarten\0"
+"Kosovo\0"
;
static const quint16 country_name_index[] = {
@@ -6825,6 +6830,7 @@ static const quint16 country_name_index[] = {
2676, // SouthSudan
2687, // Bonaire
2695, // SintMaarten
+ 2707, // Kosovo
};
static const unsigned char language_code_list[] =
@@ -7507,6 +7513,7 @@ static const unsigned char country_code_list[] =
"SS\0" // SouthSudan
"BQ\0" // Bonaire
"SX\0" // SintMaarten
+"XK\0" // Kosovo
;
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 56ed6c7534..4b4606ffab 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -62,7 +62,7 @@
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SYSTEMLOCALE
-class QSystemLocale
+class Q_CORE_EXPORT QSystemLocale
{
public:
QSystemLocale();
@@ -330,7 +330,8 @@ public:
enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
- QString dateTimeToString(const QString &format, const QDate *date, const QTime *time,
+ QString dateTimeToString(const QString &format, const QDateTime &datetime,
+ const QDate &dateOnly, const QTime &timeOnly,
const QLocale *q) const;
const QLocaleData *m_data;
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index e695ac0f4d..072a35aa4e 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -1064,15 +1064,7 @@ static Bigint *pow5mult(Bigint *b, int k)
static const int p05[3] = { 5, 25, 125 };
if ((i = k & 3) != 0)
-#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
- {
- // work around a bug on 64 bit IRIX gcc
- int *p = (int *) p05;
- b = multadd(b, p[i-1], 0);
- }
-#else
b = multadd(b, p05[i-1], 0);
-#endif
if (!(k >>= 2))
return b;
@@ -1666,15 +1658,7 @@ Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok)
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
rv = y;
if (k > 9)
-#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
- {
- // work around a bug on 64 bit IRIX gcc
- double *t = (double *) tens;
- rv = t[k - 9] * rv + z;
- }
-#else
rv = tens[k - 9] * rv + z;
-#endif
bd0 = 0;
if (nd <= DBL_DIG
@@ -2570,13 +2554,7 @@ static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt,
else {
#endif
/* Generate ilim digits, then fix them up. */
-#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
- // work around a bug on 64 bit IRIX gcc
- double *t = (double *) tens;
- eps *= t[ilim-1];
-#else
eps *= tens[ilim-1];
-#endif
for(i = 1;; i++, d *= 10.) {
L = Long(d);
d -= L;
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 449fcbca0a..c030a76666 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -557,6 +557,18 @@ public:
private:
void detach_helper();
+ bool isValidIterator(const const_iterator &ci) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_MAP_NO_ITERATOR_DEBUG)
+ const QMapNodeBase *n = ci.i;
+ while (n->parent())
+ n = n->parent();
+ return n->left == d->root();
+#else
+ Q_UNUSED(ci);
+ return true;
+#endif
+ }
};
template <class Key, class T>
@@ -670,6 +682,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K
if (d->ref.isShared())
return this->insert(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insert", "The specified const_iterator argument 'it' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -753,6 +767,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co
if (d->ref.isShared())
return this->insertMulti(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insertMulti", "The specified const_iterator argument 'pos' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -895,6 +911,29 @@ Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterato
if (it == iterator(d->end()))
return it;
+ Q_ASSERT_X(isValidIterator(const_iterator(it)), "QMap::erase", "The specified iterator argument 'it' is invalid");
+
+ if (d->ref.isShared()) {
+ const_iterator oldBegin = constBegin();
+ const_iterator old = const_iterator(it);
+ int backStepsWithSameKey = 0;
+
+ while (old != oldBegin) {
+ --old;
+ if (qMapLessThanKey(old.key(), it.key()))
+ break;
+ ++backStepsWithSameKey;
+ }
+
+ it = find(old.key()); // ensures detach
+ Q_ASSERT_X(it != iterator(d->end()), "QMap::erase", "Unable to locate same key in erase after detach.");
+
+ while (backStepsWithSameKey > 0) {
+ ++it;
+ --backStepsWithSameKey;
+ }
+ }
+
Node *n = it.i;
++it;
d->deleteNode(n);
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index 96b1b65e33..9b8691a3d8 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -57,6 +57,19 @@ struct QPair
QPair(const T1 &t1, const T2 &t2) : first(t1), second(t2) {}
// compiler-generated copy/move ctor/assignment operators are fine!
+ template <typename TT1, typename TT2>
+ QPair(const QPair<TT1, TT2> &p) : first(p.first), second(p.second) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(const QPair<TT1, TT2> &p)
+ { first = p.first; second = p.second; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ template <typename TT1, typename TT2>
+ QPair(QPair<TT1, TT2> &&p) : first(std::move(p.first)), second(std::move(p.second)) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(QPair<TT1, TT2> &&p)
+ { first = std::move(p.first); second = std::move(p.second); return *this; }
+#endif
+
T1 first;
T2 second;
};
diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc
index b0caf1aaf0..dd3df8c464 100644
--- a/src/corelib/tools/qpair.qdoc
+++ b/src/corelib/tools/qpair.qdoc
@@ -96,6 +96,26 @@
\sa qMakePair()
*/
+/*!
+ \fn QPair::QPair(const QPair<TT1, TT2> &p)
+ \since 5.2
+
+ Constructs a pair from the other pair \a p, of types TT1 and TT2. This
+ constructor will fail if \c first cannot be initialized from \c p.first or
+ if \c second cannot be initialized from \c p.second.
+
+ \sa qMakePair()
+*/
+
+/*!
+ \fn QPair &QPair::operator=(const QPair<TT1, TT2> &p)
+ \since 5.2
+
+ Copies the pair \a p onto this pair.
+
+ \sa qMakePair()
+*/
+
/*! \fn bool operator==(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
\relates QPair
diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp
index 0848754de5..fb0025c1ff 100644
--- a/src/corelib/tools/qscopedpointer.cpp
+++ b/src/corelib/tools/qscopedpointer.cpp
@@ -95,6 +95,9 @@ QT_BEGIN_NAMESPACE
this handler for pointers that were allocated with \c{new []}.
\li QScopedPointerPodDeleter - deletes the pointer using \c{free()}. Use this
handler for pointers that were allocated with \c{malloc()}.
+ \li QScopedPointerDeleteLater - deletes a pointer by calling \c{deleteLater()}
+ on it. Use this handler for pointers to QObject's that are actively
+ participating in a QEventLoop.
\endlist
You can pass your own classes as handlers, provided that they have a public
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index 2155c56e27..dd6e5bd57b 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -83,6 +83,17 @@ struct QScopedPointerPodDeleter
static inline void cleanup(void *pointer) { if (pointer) free(pointer); }
};
+#ifndef QT_NO_QOBJECT
+template <typename T>
+struct QScopedPointerObjectDeleteLater
+{
+ static inline void cleanup(T *pointer) { if (pointer) pointer->deleteLater(); }
+};
+
+class QObject;
+typedef QScopedPointerObjectDeleteLater<QObject> QScopedPointerDeleteLater;
+#endif
+
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index d5c3637293..ad2f91b983 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -70,6 +70,7 @@ public:
inline QSet<T> &operator=(const QSet<T> &other)
{ q_hash = other.q_hash; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {}
inline QSet<T> &operator=(QSet<T> &&other)
{ qSwap(q_hash, other.q_hash); return *this; }
#endif
@@ -180,7 +181,10 @@ public:
inline const_iterator cend() const { return q_hash.end(); }
inline const_iterator constEnd() const { return q_hash.constEnd(); }
iterator erase(iterator i)
- { return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i)); }
+ {
+ Q_ASSERT_X(isValidIterator(i), "QSet::erase", "The specified const_iterator argument 'i' is invalid");
+ return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i));
+ }
// more Qt
typedef iterator Iterator;
@@ -233,6 +237,10 @@ public:
private:
Hash q_hash;
+ bool isValidIterator(const iterator &i) const
+ {
+ return q_hash.isValidIterator(reinterpret_cast<const typename Hash::iterator&>(i));
+ }
};
template <class T>
@@ -253,8 +261,16 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
{
- QSet<T> copy1(*this);
- QSet<T> copy2(other);
+ QSet<T> copy1;
+ QSet<T> copy2;
+ if (size() <= other.size()) {
+ copy1 = *this;
+ copy2 = other;
+ } else {
+ copy1 = other;
+ copy2 = *this;
+ *this = copy1;
+ }
typename QSet<T>::const_iterator i = copy1.constEnd();
while (i != copy1.constBegin()) {
--i;
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index c81df7a6f2..00c523afe6 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -159,7 +159,7 @@ static int maxBasicCpuidSupported()
#if defined(Q_CC_GNU)
qintptr tmp1;
-# ifdef Q_PROCESSOR_X86_32
+# if Q_PROCESSOR_X86 < 5
// check if the CPUID instruction is supported
long cpuid_supported;
asm ("pushf\n"
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 37d28b0904..936a5d68fa 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -820,17 +820,43 @@ const QString::Null QString::null = { };
*/
/*!
+ \typedef QString::size_type
+
+ The QString::size_type typedef provides an STL-style type for sizes (int).
+*/
+
+/*!
+ \typedef QString::difference_type
+
+ The QString::size_type typedef provides an STL-style type for difference between pointers.
+*/
+
+/*!
\typedef QString::const_reference
The QString::const_reference typedef provides an STL-style
- const reference for QString.
+ const reference for a QString element (QChar).
*/
/*!
\typedef QString::reference
- The QString::const_reference typedef provides an STL-style
- reference for QString.
+ The QString::reference typedef provides an STL-style
+ reference for a QString element (QChar).
+*/
+
+/*!
+ \typedef QString::const_pointer
+
+ The QString::const_pointer typedef provides an STL-style
+ const pointer to a QString element (QChar).
+*/
+/*!
+ \typedef QString::pointer
+
+ The QString::const_pointer typedef provides an STL-style
+ pointer to a QString element (QChar).
*/
+
/*!
\typedef QString::value_type
@@ -6611,6 +6637,8 @@ void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::
for (int i = from; i < len; ++i) {
if (p[i].unicode() >= 0x80) {
simple = false;
+ if (i > from)
+ from = i - 1;
break;
}
}
@@ -6653,6 +6681,10 @@ void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::
}
}
}
+
+ if (normalizationQuickCheckHelper(data, mode, from, &from))
+ return;
+
decomposeHelper(data, mode < QString::NormalizationForm_KD, version, from);
canonicalOrderHelper(data, version, from);
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index d8aaa929dc..7010a954b4 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -657,8 +657,12 @@ public:
const_iterator constEnd() const;
// STL compatibility
+ typedef int size_type;
+ typedef qptrdiff difference_type;
typedef const QChar & const_reference;
typedef QChar & reference;
+ typedef QChar *pointer;
+ typedef const QChar *const_pointer;
typedef QChar value_type;
inline void push_back(QChar c) { append(c); }
inline void push_back(const QString &s) { append(s); }
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
index 764a4afa04..568f3aa1fb 100644
--- a/src/corelib/tools/qunicodetables.cpp
+++ b/src/corelib/tools/qunicodetables.cpp
@@ -54,819 +54,819 @@ static const unsigned short uc_property_trie[] = {
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, 7376, 7408, 7376, 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,
- 8272, 8304, 8336, 8368, 8368, 8400, 8432, 8464,
- 8496, 8528, 8560, 8592, 8624, 8656, 8688, 8720,
- 8752, 8784, 8816, 8848, 8880, 8912, 8944, 8976,
- 9008, 9040, 9072, 9104, 9136, 9168, 9200, 9232,
- 9264, 9296, 9328, 9360, 9392, 9424, 9456, 9488,
- 9520, 9552, 9584, 9616, 9648, 9680, 9712, 9744,
- 9776, 9808, 9840, 9872, 9904, 9936, 9968, 9872,
- 10000, 10032, 10064, 10096, 10128, 10160, 10192, 9872,
-
- 10224, 10256, 10288, 10320, 10352, 10384, 10416, 10448,
- 10480, 10480, 10512, 10544, 10544, 10576, 10608, 10640,
- 10672, 10704, 10736, 10704, 10768, 10800, 10832, 10864,
- 10896, 10704, 10928, 10960, 10992, 11024, 11024, 11056,
- 11088, 11120, 11120, 11120, 11120, 11120, 11120, 11120,
- 11120, 11120, 11120, 11120, 11120, 11120, 11120, 11120,
- 11120, 11120, 11120, 11152, 11184, 11216, 11216, 11248,
- 11280, 11312, 11344, 11376, 11408, 11440, 11472, 11504,
- 11536, 11568, 11600, 11632, 11568, 11664, 11696, 11728,
- 11760, 11792, 11824, 11856, 11888, 11920, 11952, 11984,
- 12016, 12048, 12080, 12112, 12144, 12176, 9872, 9872,
- 12208, 12240, 12272, 12304, 12336, 12368, 12400, 12432,
- 12464, 12496, 12528, 12560, 9872, 9872, 12592, 12624,
- 12656, 12688, 12720, 12752, 12784, 12816, 12848, 12880,
- 6512, 6512, 6512, 6512, 12912, 6512, 6512, 12944,
- 12976, 13008, 13040, 13072, 13104, 13136, 13168, 13200,
-
- 13232, 13264, 13296, 13328, 13360, 13392, 13424, 13456,
- 13488, 13520, 13552, 13584, 13616, 13648, 13680, 13712,
- 13744, 13776, 13808, 13840, 13872, 13904, 13936, 13968,
- 14000, 14032, 14064, 14096, 14128, 14160, 14192, 14224,
- 14256, 14288, 14320, 14352, 14384, 14416, 14448, 14480,
- 14256, 14256, 14256, 14256, 14512, 14544, 14576, 14608,
- 14640, 14672, 14256, 14704, 14736, 14768, 14800, 14832,
- 14864, 14896, 14928, 14960, 14992, 15024, 15056, 15088,
- 15120, 15120, 15120, 15120, 15120, 15120, 15120, 15120,
- 15152, 15152, 15152, 15152, 15184, 15216, 15248, 15280,
- 15152, 15312, 15152, 15344, 15376, 15408, 15440, 15472,
- 15504, 15536, 15568, 9872, 9872, 9872, 9872, 9872,
- 15600, 15632, 15664, 15696, 15728, 15728, 15728, 15760,
- 15792, 15824, 15856, 15888, 15920, 15952, 15952, 15984,
- 16016, 16048, 9872, 9872, 16080, 16112, 16112, 16144,
- 16112, 16112, 16112, 16112, 16112, 16112, 16176, 16208,
-
- 16240, 16272, 16304, 16336, 16368, 16400, 16432, 16464,
- 16496, 16528, 16560, 16560, 16592, 16624, 16656, 16688,
- 16720, 16752, 16784, 16816, 16752, 16848, 16880, 16912,
- 16944, 16944, 16976, 17008, 17040, 17040, 17072, 17104,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
-
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17136, 17136, 17136,
- 17136, 17136, 17136, 17136, 17136, 17168, 17200, 17200,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
-
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
-
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
-
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
-
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
-
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 17232, 17232, 17232, 17232, 17264, 17296, 17328,
-
- 17360, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 7280, 7312, 7344, 7376, 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, 8272,
+ 8304, 8336, 8368, 8400, 8400, 8432, 8464, 8496,
+ 8528, 8560, 8592, 8624, 8656, 8688, 8720, 8752,
+ 8784, 8816, 8848, 8880, 8912, 8944, 8976, 9008,
+ 9040, 9072, 9104, 9136, 9168, 9200, 9232, 9264,
+ 9296, 9328, 9360, 9392, 9424, 9456, 9488, 9520,
+ 9552, 9584, 9616, 9648, 9680, 9712, 9744, 9776,
+ 9808, 9840, 9872, 9904, 9936, 9968, 10000, 9904,
+ 10032, 10064, 10096, 10128, 10160, 10192, 10224, 9904,
+
+ 10256, 10288, 10320, 10352, 10384, 10416, 10448, 10480,
+ 10512, 10512, 10544, 10576, 10608, 10640, 10672, 10704,
+ 10736, 10768, 10800, 10768, 10832, 10864, 10896, 10928,
+ 10960, 10768, 10992, 11024, 11056, 11088, 11088, 11120,
+ 11152, 11184, 11184, 11184, 11184, 11184, 11184, 11184,
+ 11184, 11184, 11184, 11184, 11184, 11184, 11184, 11184,
+ 11184, 11184, 11184, 11216, 11248, 11280, 11280, 11312,
+ 11344, 11376, 11408, 11440, 11472, 11504, 11536, 11568,
+ 11600, 11632, 11664, 11696, 11632, 11728, 11760, 11792,
+ 11824, 11856, 11888, 11920, 11952, 11984, 12016, 12048,
+ 12080, 12112, 12144, 12176, 12208, 12240, 9904, 9904,
+ 12272, 12304, 12336, 12368, 12400, 12432, 12464, 12496,
+ 12528, 12560, 12592, 12624, 9904, 9904, 12656, 12688,
+ 12720, 12752, 12784, 12816, 12848, 12880, 12912, 12944,
+ 12976, 12976, 12976, 12976, 13008, 12976, 12976, 13040,
+ 13072, 13104, 13136, 13168, 13200, 13232, 13264, 13296,
+
+ 13328, 13360, 13392, 13424, 13456, 13488, 13520, 13552,
+ 13584, 13616, 13648, 13680, 13712, 13744, 13776, 13808,
+ 13840, 13872, 13904, 13936, 13968, 14000, 14032, 14064,
+ 14096, 14128, 14160, 14192, 14224, 14256, 14288, 14320,
+ 14352, 14384, 14416, 14448, 14480, 14512, 14544, 14576,
+ 14352, 14352, 14352, 14352, 14608, 14640, 14672, 14704,
+ 14736, 14768, 14352, 14800, 14832, 14864, 14896, 14928,
+ 14960, 14992, 15024, 15056, 15088, 15120, 15152, 15184,
+ 15216, 15216, 15216, 15216, 15216, 15216, 15216, 15216,
+ 15248, 15248, 15248, 15248, 15280, 15312, 15344, 15376,
+ 15408, 15440, 15248, 15472, 15504, 15536, 15568, 15600,
+ 15632, 15664, 15696, 9904, 9904, 9904, 9904, 9904,
+ 15728, 15760, 15792, 15824, 15856, 15856, 15856, 15888,
+ 15920, 15952, 15984, 16016, 16048, 16080, 16080, 16112,
+ 16144, 16176, 9904, 9904, 16208, 16240, 16240, 16272,
+ 16304, 16304, 16304, 16304, 16304, 16304, 16336, 16368,
+
+ 16400, 16432, 16464, 16496, 16528, 16560, 16592, 16624,
+ 16656, 16688, 16720, 16720, 16752, 16784, 16816, 16848,
+ 16880, 16912, 16944, 16976, 16912, 17008, 17040, 17072,
+ 17104, 17104, 17136, 17168, 17200, 17200, 17232, 17264,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
+ 17296, 17296, 17296, 17296, 17296, 17328, 17360, 17360,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17424, 17456, 17488, 17520,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
+ 17392, 17392, 17392, 17392, 17392, 17424, 17456, 17488,
+
+ 17520, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
17552, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
- 17584, 17616, 17648, 17680, 17712, 17744, 17744, 17776,
- 17808, 17840, 17872, 17904, 17936, 17968, 9872, 18000,
- 18032, 18064, 18096, 18128, 18160, 18192, 18224, 18256,
- 18288, 18320, 18352, 18384, 18416, 18448, 18480, 9872,
- 18512, 18544, 18576, 18608, 18640, 18672, 18704, 18736,
- 18768, 18800, 9872, 9872, 9872, 9872, 18832, 18864,
- 18896, 18928, 18960, 18992, 19024, 19056, 19088, 18896,
- 18928, 18960, 18992, 19024, 19056, 19088, 18896, 18928,
- 18960, 18992, 19024, 19056, 19088, 18896, 18928, 18960,
- 18992, 19024, 19056, 19088, 18896, 18928, 18960, 18992,
-
- 19024, 19056, 19088, 18896, 18928, 18960, 18992, 19024,
- 19056, 19088, 18896, 18928, 18960, 18992, 19024, 19056,
- 19088, 18896, 18928, 18960, 18992, 19024, 19056, 19088,
- 18896, 18928, 18960, 18992, 19024, 19056, 19088, 18896,
- 18928, 18960, 18992, 19024, 19056, 19088, 18896, 18928,
- 18960, 18992, 19024, 19056, 19088, 18896, 18928, 18960,
- 18992, 19024, 19056, 19088, 18896, 18928, 18960, 18992,
- 19024, 19056, 19088, 18896, 18928, 18960, 18992, 19024,
- 19056, 19088, 18896, 18928, 18960, 18992, 19024, 19056,
- 19088, 18896, 18928, 18960, 18992, 19024, 19056, 19088,
- 18896, 18928, 18960, 18992, 19024, 19056, 19088, 18896,
- 18928, 18960, 18992, 19024, 19056, 19088, 18896, 18928,
- 18960, 18992, 19024, 19056, 19088, 18896, 18928, 18960,
- 18992, 19024, 19056, 19088, 18896, 18928, 18960, 18992,
- 19024, 19056, 19088, 18896, 18928, 18960, 18992, 19024,
- 19056, 19088, 18896, 18928, 18960, 18992, 19024, 19056,
-
- 19088, 18896, 18928, 18960, 18992, 19024, 19056, 19088,
- 18896, 18928, 18960, 18992, 19024, 19056, 19088, 18896,
- 18928, 18960, 18992, 19024, 19056, 19088, 18896, 18928,
- 18960, 18992, 19024, 19056, 19088, 18896, 18928, 18960,
- 18992, 19024, 19056, 19088, 18896, 18928, 18960, 18992,
- 19024, 19056, 19088, 18896, 18928, 18960, 18992, 19024,
- 19056, 19088, 18896, 18928, 18960, 18992, 19024, 19056,
- 19088, 18896, 18928, 18960, 18992, 19024, 19056, 19088,
- 18896, 18928, 18960, 18992, 19024, 19056, 19088, 18896,
- 18928, 18960, 18992, 19024, 19056, 19088, 18896, 18928,
- 18960, 18992, 19024, 19056, 19088, 18896, 18928, 18960,
- 18992, 19024, 19056, 19088, 18896, 18928, 18960, 18992,
- 19024, 19056, 19088, 18896, 18928, 18960, 18992, 19024,
- 19056, 19088, 18896, 18928, 18960, 18992, 19024, 19056,
- 19088, 18896, 18928, 18960, 18992, 19024, 19056, 19088,
- 18896, 18928, 18960, 18992, 19024, 19056, 19088, 18896,
-
- 18928, 18960, 18992, 19024, 19056, 19088, 18896, 18928,
- 18960, 18992, 19024, 19056, 19088, 18896, 18928, 18960,
- 18992, 19024, 19056, 19088, 18896, 18928, 18960, 18992,
- 19024, 19056, 19088, 18896, 18928, 18960, 18992, 19024,
- 19056, 19088, 18896, 18928, 18960, 18992, 19024, 19056,
- 19088, 18896, 18928, 18960, 18992, 19024, 19056, 19088,
- 18896, 18928, 18960, 18992, 19024, 19056, 19088, 18896,
- 18928, 18960, 18992, 19024, 19056, 19120, 19152, 19184,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
- 19216, 19216, 19216, 19216, 19216, 19216, 19216, 19216,
-
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
-
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 19248, 19248, 19248, 19248, 19248, 19248, 19248, 19248,
- 17232, 17232, 17232, 17232, 17232, 17232, 17232, 17232,
- 17232, 19280, 19312, 19344, 19376, 19376, 19408, 17328,
- 19440, 19472, 19504, 19536, 19536, 19568, 19600, 19536,
- 19536, 19536, 19536, 19536, 19536, 19536, 19536, 19536,
- 19536, 19632, 19664, 19536, 19696, 19536, 19728, 19760,
- 19792, 19824, 19856, 19888, 19536, 19536, 19536, 19920,
- 19952, 19984, 20016, 20048, 20080, 20112, 20144, 20176,
-
- 20208, 20240, 20272, 9872, 20304, 20304, 20304, 20336,
- 20368, 20400, 20432, 20464, 20496, 9872, 20528, 20560,
- 9872, 9872, 9872, 9872, 20592, 20624, 20656, 9872,
- 20688, 20720, 20752, 9872, 20784, 20816, 20848, 9872,
- 20880, 20912, 20944, 20976, 21008, 21040, 9872, 9872,
- 9872, 9872, 9872, 9872, 9872, 9872, 9872, 9872,
- 9872, 9872, 9872, 9872, 9872, 9872, 9872, 9872,
- 9872, 9872, 9872, 9872, 9872, 9872, 9872, 9872,
- 21072, 21104, 21136, 8368, 8368, 8368, 8368, 8368,
- 21168, 21200, 8368, 8368, 21232, 21264, 8368, 8368,
- 21296, 21328, 21360, 21392, 8368, 8368, 8368, 8368,
- 21424, 21456, 21488, 21520, 8368, 8368, 8368, 8368,
- 21552, 21552, 21584, 8368, 8368, 8368, 8368, 8368,
- 8368, 8368, 8368, 8368, 8368, 8368, 8368, 8368,
- 8368, 8368, 8368, 21616, 8368, 8368, 8368, 8368,
- 8368, 8368, 8368, 8368, 8368, 8368, 8368, 8368,
+ 17552, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
+ 17552, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
+ 17552, 17552, 17552, 17552, 17584, 17616, 17648, 17680,
+ 17712, 17712, 17712, 17712, 17712, 17712, 17712, 17712,
+ 17744, 17776, 17808, 17840, 17872, 17904, 17904, 17936,
+ 17968, 18000, 18032, 18064, 18096, 18128, 9904, 18160,
+ 18192, 18224, 18256, 18288, 18320, 18352, 18384, 18416,
+ 18448, 18480, 18512, 18544, 18576, 18608, 18640, 9904,
+ 18672, 18704, 18736, 18768, 18800, 18832, 18864, 18896,
+ 18928, 18960, 9904, 9904, 9904, 9904, 18992, 19024,
+ 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
+
+ 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
+
+ 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
+
+ 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
+ 19088, 19120, 19152, 19184, 19216, 19280, 19312, 19344,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+ 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
+
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19472, 19504, 19536, 19568, 19600, 19600, 19632, 17488,
+ 19664, 19696, 19728, 19760, 19760, 19792, 19824, 19760,
+ 19760, 19760, 19760, 19760, 19760, 19760, 19760, 19760,
+ 19760, 19856, 19888, 19760, 19920, 19760, 19952, 19984,
+ 20016, 20048, 20080, 20112, 19760, 19760, 19760, 20144,
+ 20176, 20208, 20240, 20272, 20304, 20336, 20368, 20400,
+
+ 20432, 20464, 20496, 9904, 20528, 20528, 20528, 20560,
+ 20592, 20624, 20656, 20688, 20720, 9904, 20752, 20784,
+ 9904, 9904, 9904, 9904, 20816, 20848, 20880, 9904,
+ 20912, 20944, 20976, 9904, 21008, 21040, 21072, 9904,
+ 21104, 21136, 21168, 21200, 21232, 21264, 9904, 9904,
+ 9904, 9904, 9904, 9904, 9904, 9904, 9904, 9904,
+ 9904, 9904, 9904, 9904, 9904, 9904, 9904, 9904,
+ 9904, 9904, 9904, 9904, 9904, 9904, 9904, 9904,
+ 21296, 21328, 21360, 8400, 8400, 8400, 8400, 8400,
+ 21392, 21424, 8400, 8400, 21456, 21488, 8400, 8400,
+ 21520, 21552, 21584, 21616, 8400, 8400, 8400, 8400,
+ 21648, 21680, 21712, 21744, 8400, 8400, 8400, 8400,
+ 21776, 21776, 21808, 8400, 8400, 8400, 8400, 8400,
+ 8400, 8400, 8400, 8400, 8400, 8400, 8400, 8400,
+ 8400, 8400, 8400, 21840, 8400, 8400, 8400, 8400,
+ 8400, 8400, 8400, 8400, 8400, 8400, 8400, 8400,
// 0x11000 - 0x110000
- 21648, 21904, 22160, 22160, 22160, 22160, 22416, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22672, 22672, 22672, 22928, 23184, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 23440, 23440, 23696, 23952, 24208, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 24464, 24464, 24720, 22160, 22160, 22160, 22160, 24976,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 25232, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 25488, 25744, 26000, 26256, 26512, 26768, 27024, 27280,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 27536, 27536, 27536, 27536, 27536, 27536, 27792, 27536,
- 28048, 28304, 28560, 28816, 29072, 29328, 29584, 29840,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
-
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30352, 30352,
- 30352, 30352, 30352, 30352, 30352, 30352, 30608, 30864,
- 30864, 30864, 30864, 30864, 30864, 30864, 30864, 30864,
- 30864, 30864, 30864, 30864, 30864, 30864, 30864, 31120,
- 31376, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 30352, 30352, 31888, 31632, 31632, 31632, 31632, 32144,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
-
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 31632,
- 31632, 31632, 31632, 31632, 31632, 31632, 31632, 32144,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 32400, 32656, 32912, 32912, 32912, 32912, 32912, 32912,
- 32912, 32912, 32912, 32912, 32912, 32912, 32912, 32912,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
-
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 22160,
- 22160, 22160, 22160, 22160, 22160, 22160, 22160, 30096,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
-
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33424,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
-
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33168,
- 33168, 33168, 33168, 33168, 33168, 33168, 33168, 33424,
+ 21872, 22128, 22384, 22384, 22384, 22384, 22640, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22896, 22896, 22896, 23152, 23408, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 23664, 23664, 23920, 24176, 24432, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 24688, 24688, 24944, 22384, 22384, 22384, 22384, 25200,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 25456, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 25712, 25968, 26224, 26480, 26736, 26992, 27248, 27504,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 27760, 27760, 27760, 27760, 27760, 27760, 28016, 27760,
+ 28272, 28528, 28784, 29040, 29296, 29552, 29808, 30064,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
+ 30576, 30576, 30576, 30576, 30576, 30576, 30832, 31088,
+ 31088, 31088, 31088, 31088, 31088, 31088, 31088, 31088,
+ 31088, 31088, 31088, 31088, 31088, 31088, 31088, 31344,
+ 31600, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 32112, 32112, 32368, 31856, 31856, 31856, 31856, 32624,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
+ 31856, 31856, 31856, 31856, 31856, 31856, 31856, 32624,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 32880, 33136, 33392, 33392, 33392, 33392, 33392, 33392,
+ 33392, 33392, 33392, 33392, 33392, 33392, 33392, 33392,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
+ 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33904,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
+ 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33904,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -895,1274 +895,1289 @@ static const unsigned short uc_property_trie[] = {
0, 0, 0, 0, 0, 0, 0, 0,
48, 49, 50, 12, 12, 12, 51, 14,
- 42, 51, 52, 53, 36, 54, 51, 42,
- 55, 56, 57, 58, 59, 60, 14, 61,
- 42, 62, 52, 63, 64, 64, 64, 49,
-
- 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, 65,
-
- 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, 66,
-
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
-
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 69, 70, 67, 68, 67, 68, 67, 68,
- 71, 67, 68, 67, 68, 67, 68, 67,
-
- 68, 67, 68, 67, 68, 67, 68, 67,
- 68, 72, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
-
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 73, 67, 68, 67, 68, 67, 68, 74,
-
- 75, 76, 67, 68, 67, 68, 77, 67,
- 68, 78, 78, 67, 68, 71, 79, 80,
- 81, 67, 68, 78, 82, 83, 84, 85,
- 67, 68, 86, 71, 84, 87, 88, 89,
-
- 67, 68, 67, 68, 67, 68, 90, 67,
- 68, 90, 71, 71, 67, 68, 90, 67,
- 68, 91, 91, 67, 68, 67, 68, 92,
- 67, 68, 71, 93, 67, 68, 71, 94,
-
- 93, 93, 93, 93, 95, 96, 97, 95,
- 96, 97, 95, 96, 97, 67, 68, 67,
- 68, 67, 68, 67, 68, 67, 68, 67,
- 68, 67, 68, 67, 68, 98, 67, 68,
-
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 99, 95, 96, 97, 67, 68, 100, 101,
- 102, 103, 67, 68, 67, 68, 67, 68,
-
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 102, 103, 102, 103, 102, 103, 102, 103,
-
- 104, 105, 102, 103, 102, 103, 102, 103,
- 102, 103, 102, 103, 102, 103, 102, 103,
- 102, 103, 102, 103, 105, 105, 105, 106,
- 106, 106, 107, 108, 109, 110, 111, 112,
-
- 112, 108, 113, 114, 115, 116, 117, 113,
- 117, 113, 117, 113, 117, 113, 117, 113,
- 118, 119, 120, 121, 122, 71, 123, 123,
- 71, 124, 71, 125, 71, 71, 71, 71,
-
- 123, 71, 71, 126, 71, 127, 128, 71,
- 129, 130, 71, 131, 71, 71, 71, 130,
- 71, 132, 133, 71, 71, 134, 71, 71,
- 71, 71, 71, 71, 71, 135, 71, 71,
-
- 136, 71, 71, 136, 71, 71, 71, 71,
- 136, 137, 138, 138, 139, 71, 71, 71,
- 71, 71, 140, 71, 93, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71,
-
- 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 141, 141, 141, 141, 141, 105, 105,
- 142, 142, 142, 142, 142, 142, 142, 142,
- 142, 143, 143, 144, 144, 144, 144, 144,
-
- 145, 145, 42, 42, 42, 42, 143, 143,
- 146, 143, 143, 143, 146, 143, 143, 143,
- 144, 144, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 147,
-
- 142, 142, 142, 142, 142, 42, 42, 42,
- 42, 42, 148, 148, 149, 150, 151, 152,
- 152, 152, 152, 152, 152, 152, 152, 152,
- 152, 152, 152, 152, 152, 152, 152, 152,
-
- 153, 153, 153, 153, 153, 153, 153, 153,
- 153, 153, 153, 153, 153, 153, 153, 153,
- 153, 153, 153, 153, 153, 154, 155, 155,
- 155, 155, 154, 156, 155, 155, 155, 155,
-
- 155, 157, 157, 155, 155, 155, 155, 157,
- 157, 155, 155, 155, 155, 155, 155, 155,
- 155, 155, 155, 155, 158, 158, 158, 158,
- 158, 155, 155, 155, 155, 153, 153, 153,
-
- 153, 153, 153, 153, 153, 159, 160, 161,
- 161, 161, 160, 160, 160, 161, 161, 162,
- 163, 163, 163, 164, 164, 164, 164, 163,
- 165, 166, 166, 167, 168, 169, 169, 170,
-
- 171, 171, 172, 173, 173, 173, 173, 173,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 174, 175, 174, 175, 143, 176, 174, 175,
- 177, 177, 178, 179, 179, 179, 34, 177,
-
- 177, 177, 177, 177, 176, 42, 180, 61,
- 181, 181, 181, 177, 182, 177, 183, 183,
- 184, 185, 185, 185, 185, 185, 185, 185,
- 185, 185, 185, 185, 185, 185, 185, 185,
-
- 185, 185, 177, 185, 185, 185, 185, 185,
- 185, 185, 185, 185, 186, 187, 187, 187,
- 188, 189, 189, 189, 189, 189, 189, 189,
- 189, 189, 189, 189, 189, 189, 189, 189,
-
- 189, 189, 190, 189, 189, 189, 189, 189,
- 189, 189, 189, 189, 191, 192, 192, 193,
- 194, 195, 196, 196, 196, 197, 198, 199,
- 200, 201, 202, 203, 202, 203, 202, 203,
-
- 202, 203, 204, 205, 204, 205, 204, 205,
- 204, 205, 204, 205, 204, 205, 204, 205,
- 206, 207, 208, 209, 210, 211, 212, 213,
- 214, 215, 213, 214, 216, 217, 217, 217,
-
- 218, 219, 219, 219, 219, 219, 219, 219,
- 219, 219, 219, 219, 219, 218, 219, 219,
- 220, 220, 220, 220, 220, 220, 220, 220,
- 220, 220, 220, 220, 220, 220, 220, 220,
-
- 220, 220, 220, 220, 220, 220, 220, 220,
- 220, 220, 220, 220, 220, 220, 220, 220,
- 221, 221, 221, 221, 221, 221, 221, 221,
- 221, 221, 221, 221, 221, 221, 221, 221,
-
- 221, 221, 221, 221, 221, 221, 221, 221,
- 221, 221, 221, 221, 221, 221, 221, 221,
- 222, 223, 223, 223, 223, 223, 223, 223,
- 223, 223, 223, 223, 223, 222, 223, 223,
-
- 224, 225, 224, 225, 224, 225, 224, 225,
- 224, 225, 224, 225, 224, 225, 224, 225,
- 224, 225, 224, 225, 224, 225, 224, 225,
- 224, 225, 224, 225, 224, 225, 224, 225,
-
- 224, 225, 226, 227, 227, 153, 153, 228,
- 229, 229, 230, 231, 232, 233, 232, 233,
- 224, 225, 224, 225, 224, 225, 224, 225,
- 224, 225, 224, 225, 224, 225, 224, 225,
-
- 234, 224, 225, 224, 225, 230, 231, 224,
- 225, 230, 231, 224, 225, 230, 231, 235,
- 224, 225, 224, 225, 224, 225, 224, 225,
- 224, 225, 224, 225, 224, 225, 224, 225,
-
- 224, 225, 224, 225, 224, 225, 224, 225,
- 224, 225, 224, 225, 232, 233, 224, 225,
- 224, 225, 224, 225, 224, 225, 236, 237,
- 224, 225, 238, 239, 238, 239, 238, 239,
-
- 230, 231, 230, 231, 230, 231, 230, 231,
- 230, 231, 230, 231, 230, 231, 230, 231,
- 238, 239, 238, 239, 240, 241, 240, 241,
- 240, 241, 240, 241, 240, 241, 240, 241,
-
- 240, 241, 240, 241, 242, 243, 244, 245,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246,
-
- 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 177,
- 177, 247, 248, 248, 249, 250, 249, 248,
-
- 177, 251, 251, 251, 251, 251, 251, 251,
- 251, 251, 251, 251, 251, 251, 251, 251,
- 251, 251, 251, 251, 251, 251, 251, 251,
- 251, 251, 251, 251, 251, 251, 251, 251,
-
- 251, 251, 251, 251, 251, 251, 251, 252,
- 177, 253, 254, 177, 177, 177, 177, 255,
- 256, 257, 258, 258, 258, 258, 257, 258,
- 258, 258, 259, 257, 258, 258, 258, 258,
-
- 258, 258, 260, 257, 257, 257, 257, 257,
- 258, 258, 257, 258, 258, 259, 261, 258,
- 262, 263, 264, 265, 266, 267, 268, 269,
- 270, 271, 272, 273, 274, 275, 276, 277,
-
- 278, 279, 280, 278, 258, 260, 281, 282,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 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, 256, 256, 256, 256, 256,
- 283, 283, 283, 284, 285, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
-
- 286, 286, 286, 286, 287, 288, 289, 289,
- 290, 291, 291, 292, 19, 293, 294, 294,
- 295, 295, 295, 295, 295, 295, 296, 296,
- 297, 298, 299, 300, 288, 288, 301, 302,
-
- 303, 304, 305, 305, 305, 305, 306, 305,
- 306, 305, 306, 306, 306, 306, 306, 305,
- 305, 305, 305, 306, 306, 306, 306, 306,
- 306, 306, 306, 307, 307, 307, 307, 307,
-
- 308, 306, 306, 306, 306, 306, 306, 306,
- 305, 306, 306, 309, 310, 311, 312, 313,
- 314, 315, 316, 160, 160, 161, 317, 295,
- 295, 318, 318, 318, 319, 318, 318, 320,
-
- 321, 322, 323, 324, 325, 326, 327, 328,
- 329, 330, 331, 332, 333, 334, 335, 335,
- 336, 305, 305, 305, 304, 305, 305, 305,
- 306, 306, 306, 306, 306, 306, 306, 306,
-
- 306, 306, 306, 306, 306, 306, 306, 306,
- 305, 305, 305, 305, 305, 305, 305, 305,
- 305, 305, 305, 305, 305, 305, 305, 305,
- 305, 305, 306, 306, 306, 306, 306, 306,
-
- 306, 306, 306, 306, 306, 306, 306, 306,
- 306, 306, 306, 306, 306, 306, 306, 306,
- 306, 306, 306, 306, 306, 306, 306, 306,
- 337, 337, 306, 306, 306, 306, 306, 337,
-
- 305, 306, 306, 305, 305, 305, 305, 305,
- 305, 305, 305, 305, 306, 305, 306, 338,
- 306, 306, 305, 305, 339, 305, 340, 340,
- 340, 340, 340, 340, 340, 341, 342, 340,
-
- 340, 340, 340, 343, 340, 344, 344, 340,
- 340, 342, 343, 340, 340, 343, 345, 345,
- 346, 347, 348, 349, 350, 351, 352, 353,
- 354, 355, 337, 337, 337, 356, 356, 357,
-
- 358, 358, 358, 359, 359, 359, 359, 359,
- 359, 359, 359, 359, 359, 359, 288, 360,
- 361, 362, 363, 363, 363, 361, 361, 361,
- 361, 361, 363, 363, 363, 363, 361, 363,
-
- 363, 363, 363, 363, 363, 363, 363, 363,
- 361, 363, 361, 363, 361, 364, 364, 365,
- 366, 367, 366, 366, 367, 366, 366, 367,
- 367, 367, 366, 367, 367, 366, 367, 366,
-
- 366, 366, 367, 366, 367, 366, 367, 366,
- 367, 366, 366, 288, 288, 365, 364, 364,
- 368, 368, 368, 368, 368, 368, 368, 368,
- 368, 369, 369, 369, 368, 368, 368, 368,
-
- 368, 368, 368, 368, 368, 368, 368, 368,
- 368, 368, 368, 369, 369, 368, 307, 307,
- 307, 370, 307, 370, 370, 307, 307, 307,
- 370, 370, 307, 307, 307, 307, 307, 307,
-
- 371, 371, 371, 371, 371, 371, 371, 371,
- 371, 371, 371, 371, 371, 371, 371, 371,
- 371, 371, 371, 371, 371, 371, 371, 371,
- 371, 371, 371, 371, 371, 371, 371, 371,
-
- 371, 371, 371, 371, 371, 371, 372, 372,
- 372, 372, 372, 372, 372, 372, 372, 372,
- 372, 373, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
-
- 374, 375, 376, 377, 378, 379, 380, 381,
- 382, 383, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
-
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 385, 385, 385, 385, 385,
- 385, 385, 386, 385, 387, 387, 388, 389,
- 390, 391, 392, 256, 256, 256, 256, 256,
-
- 393, 393, 393, 393, 393, 393, 393, 393,
- 393, 393, 393, 393, 393, 393, 393, 393,
- 393, 393, 393, 393, 393, 393, 394, 394,
- 394, 394, 395, 394, 394, 394, 394, 394,
-
- 394, 394, 394, 394, 395, 394, 394, 394,
- 395, 394, 394, 394, 394, 394, 256, 256,
- 396, 396, 396, 396, 396, 396, 396, 396,
- 396, 396, 396, 396, 396, 396, 396, 256,
-
- 397, 398, 398, 398, 398, 398, 397, 398,
- 398, 397, 398, 398, 398, 398, 398, 397,
- 398, 398, 398, 398, 397, 398, 399, 399,
- 399, 400, 400, 400, 256, 256, 401, 256,
-
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
-
- 402, 288, 402, 402, 402, 402, 402, 402,
- 402, 402, 403, 403, 403, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
-
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
-
- 288, 288, 288, 288, 404, 404, 405, 404,
- 404, 405, 404, 404, 404, 405, 405, 405,
- 406, 407, 408, 404, 404, 404, 405, 404,
- 404, 405, 405, 404, 404, 404, 404, 288,
-
- 409, 410, 410, 411, 412, 413, 413, 413,
- 413, 413, 413, 413, 413, 413, 413, 413,
- 413, 413, 413, 413, 413, 413, 413, 413,
- 413, 413, 413, 413, 413, 413, 413, 413,
-
- 413, 413, 413, 413, 413, 413, 413, 413,
- 413, 413, 413, 413, 413, 413, 413, 413,
- 413, 413, 413, 413, 413, 413, 413, 413,
- 413, 413, 414, 415, 416, 413, 411, 411,
-
- 411, 410, 410, 410, 410, 410, 410, 410,
- 410, 411, 411, 411, 411, 417, 418, 415,
- 413, 153, 155, 419, 419, 409, 414, 414,
- 413, 413, 413, 413, 413, 413, 413, 413,
-
- 413, 413, 410, 410, 420, 420, 421, 422,
- 423, 424, 425, 426, 427, 428, 429, 430,
- 431, 432, 433, 434, 434, 434, 434, 434,
- 177, 435, 435, 436, 436, 437, 436, 436,
-
- 177, 438, 439, 439, 177, 440, 440, 440,
- 440, 440, 440, 440, 440, 177, 177, 440,
- 440, 177, 177, 440, 440, 440, 440, 440,
- 440, 440, 440, 440, 440, 440, 440, 440,
-
- 440, 440, 440, 440, 440, 440, 440, 440,
- 440, 177, 440, 440, 440, 440, 440, 440,
- 440, 177, 440, 177, 177, 177, 440, 440,
- 440, 440, 177, 177, 441, 442, 443, 439,
-
- 439, 438, 438, 438, 438, 177, 177, 439,
- 439, 177, 177, 439, 439, 444, 445, 177,
- 177, 177, 177, 177, 177, 177, 177, 443,
- 177, 177, 177, 177, 440, 440, 177, 440,
-
- 440, 440, 438, 438, 177, 177, 446, 447,
- 448, 449, 450, 451, 452, 453, 454, 455,
- 440, 440, 456, 456, 457, 457, 457, 457,
- 457, 458, 459, 460, 177, 177, 177, 177,
-
- 177, 461, 462, 463, 177, 464, 464, 464,
- 464, 464, 464, 177, 177, 177, 177, 464,
- 464, 177, 177, 464, 464, 464, 464, 464,
- 464, 464, 464, 464, 464, 464, 464, 464,
-
- 464, 464, 464, 464, 464, 464, 464, 464,
- 464, 177, 464, 464, 464, 464, 464, 464,
- 464, 177, 464, 464, 177, 464, 464, 177,
- 464, 464, 177, 177, 465, 177, 466, 466,
-
- 466, 462, 462, 177, 177, 177, 177, 462,
- 462, 177, 177, 462, 462, 467, 177, 177,
- 177, 468, 177, 177, 177, 177, 177, 177,
- 177, 464, 464, 464, 464, 177, 464, 177,
-
- 177, 177, 177, 177, 177, 177, 469, 470,
- 471, 472, 473, 474, 475, 476, 477, 478,
- 462, 462, 464, 464, 464, 468, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 479, 479, 480, 177, 481, 481, 481,
- 481, 481, 481, 481, 482, 481, 177, 481,
- 481, 481, 177, 481, 481, 481, 481, 481,
- 481, 481, 481, 481, 481, 481, 481, 481,
-
- 481, 481, 481, 481, 481, 481, 481, 481,
- 481, 177, 481, 481, 481, 481, 481, 481,
- 481, 177, 481, 481, 177, 481, 481, 481,
- 481, 481, 177, 177, 483, 481, 480, 480,
-
- 480, 479, 479, 479, 479, 479, 177, 479,
- 479, 480, 177, 480, 480, 484, 177, 177,
- 481, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 481, 482, 485, 485, 177, 177, 486, 487,
+ 52, 51, 53, 54, 36, 55, 51, 52,
+ 56, 57, 58, 59, 60, 61, 14, 62,
+ 52, 63, 53, 64, 65, 65, 65, 49,
+
+ 66, 66, 66, 66, 66, 66, 38, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 38, 66, 66, 66, 66, 66, 66, 36,
+ 38, 66, 66, 66, 66, 66, 38, 67,
+
+ 68, 68, 68, 68, 68, 68, 44, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 44, 68, 68, 68, 68, 68, 68, 36,
+ 44, 68, 68, 68, 68, 68, 44, 69,
+
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 72, 73, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+
+ 70, 71, 70, 71, 70, 71, 72, 73,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 74, 75, 76, 77, 70, 71, 70, 71,
+ 78, 70, 71, 70, 71, 70, 71, 76,
+
+ 77, 72, 73, 70, 71, 70, 71, 70,
+ 71, 79, 72, 73, 70, 71, 70, 71,
+ 70, 71, 72, 73, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+
+ 70, 71, 70, 71, 70, 71, 72, 73,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 80, 70, 71, 70, 71, 70, 71, 81,
+
+ 82, 83, 72, 73, 72, 73, 84, 72,
+ 73, 85, 85, 72, 73, 78, 86, 87,
+ 88, 72, 73, 85, 89, 90, 91, 92,
+ 72, 73, 93, 78, 91, 94, 95, 96,
+
+ 70, 71, 72, 73, 72, 73, 97, 72,
+ 73, 97, 78, 78, 72, 73, 97, 70,
+ 71, 98, 98, 72, 73, 72, 73, 99,
+ 72, 73, 78, 100, 72, 73, 78, 101,
+
+ 100, 100, 100, 100, 102, 103, 104, 102,
+ 103, 104, 102, 103, 104, 70, 71, 70,
+ 71, 70, 71, 70, 71, 70, 71, 70,
+ 71, 70, 71, 70, 71, 105, 70, 71,
+
+ 70, 71, 70, 71, 72, 73, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 106, 102, 103, 104, 70, 71, 107, 108,
+ 109, 110, 70, 71, 70, 71, 70, 71,
+
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 109, 110, 109, 110, 111, 112, 109, 110,
+
+ 113, 114, 111, 112, 111, 112, 109, 110,
+ 109, 110, 109, 110, 109, 110, 109, 110,
+ 109, 110, 109, 110, 114, 114, 114, 115,
+ 115, 115, 116, 117, 118, 119, 120, 121,
+
+ 121, 117, 122, 123, 124, 125, 126, 122,
+ 126, 122, 126, 122, 126, 122, 126, 122,
+ 127, 128, 129, 130, 131, 78, 132, 132,
+ 78, 133, 78, 134, 78, 78, 78, 78,
+
+ 132, 78, 78, 135, 78, 136, 137, 78,
+ 138, 139, 78, 140, 78, 78, 78, 139,
+ 78, 141, 142, 78, 78, 143, 78, 78,
+ 78, 78, 78, 78, 78, 144, 78, 78,
+
+ 145, 78, 78, 145, 78, 78, 78, 78,
+ 145, 146, 147, 147, 148, 78, 78, 78,
+ 78, 78, 149, 78, 100, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78,
+
+ 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 150, 150, 150, 150, 150, 114, 114,
+ 151, 151, 151, 151, 151, 151, 151, 151,
+ 151, 152, 152, 153, 153, 153, 153, 153,
+
+ 154, 154, 42, 42, 42, 42, 152, 152,
+ 155, 152, 152, 152, 155, 152, 152, 152,
+ 153, 153, 42, 42, 42, 42, 42, 42,
+ 52, 52, 52, 52, 52, 52, 42, 156,
+
+ 151, 151, 151, 151, 151, 42, 42, 42,
+ 42, 42, 157, 157, 158, 159, 160, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161,
+
+ 162, 162, 162, 162, 162, 163, 162, 162,
+ 162, 162, 162, 162, 162, 163, 163, 162,
+ 163, 162, 163, 162, 162, 164, 165, 165,
+ 165, 165, 164, 166, 165, 165, 165, 165,
+
+ 165, 167, 167, 168, 168, 168, 168, 169,
+ 169, 165, 165, 165, 165, 168, 168, 165,
+ 168, 168, 165, 165, 170, 170, 170, 170,
+ 171, 165, 165, 165, 165, 163, 163, 163,
+
+ 172, 172, 162, 172, 172, 173, 174, 175,
+ 175, 175, 174, 174, 174, 175, 175, 176,
+ 177, 177, 177, 178, 178, 178, 178, 177,
+ 179, 180, 180, 181, 182, 183, 183, 184,
+
+ 185, 185, 186, 187, 187, 187, 187, 187,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 188, 189, 188, 189, 190, 191, 188, 189,
+ 192, 192, 193, 194, 194, 194, 195, 192,
+
+ 192, 192, 192, 192, 196, 197, 198, 199,
+ 200, 200, 200, 192, 201, 192, 202, 202,
+ 203, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+
+ 204, 204, 192, 204, 204, 204, 204, 204,
+ 204, 204, 205, 205, 206, 207, 207, 207,
+ 208, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209,
+
+ 209, 209, 210, 209, 209, 209, 209, 209,
+ 209, 209, 211, 211, 212, 213, 213, 214,
+ 215, 216, 217, 218, 218, 219, 220, 221,
+ 222, 223, 224, 225, 224, 225, 224, 225,
+
+ 224, 225, 226, 227, 226, 227, 226, 227,
+ 226, 227, 226, 227, 226, 227, 226, 227,
+ 228, 229, 230, 231, 232, 233, 234, 235,
+ 236, 237, 235, 236, 238, 239, 239, 239,
+
+ 240, 241, 242, 241, 242, 242, 242, 241,
+ 242, 242, 242, 242, 241, 240, 241, 242,
+ 243, 243, 243, 243, 243, 243, 243, 243,
+ 243, 244, 243, 243, 243, 243, 243, 243,
+
+ 243, 243, 243, 243, 243, 243, 243, 243,
+ 243, 243, 243, 243, 243, 243, 243, 243,
+ 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 246, 245, 245, 245, 245, 245, 245,
+
+ 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245,
+ 247, 248, 249, 248, 249, 249, 249, 248,
+ 249, 249, 249, 249, 248, 247, 248, 249,
+
+ 250, 251, 250, 251, 250, 251, 250, 251,
+ 250, 251, 250, 251, 250, 251, 250, 251,
+ 250, 251, 250, 251, 250, 251, 252, 253,
+ 250, 251, 250, 251, 250, 251, 250, 251,
+
+ 250, 251, 254, 255, 255, 163, 163, 256,
+ 257, 257, 258, 259, 260, 261, 260, 261,
+ 250, 251, 250, 251, 250, 251, 250, 251,
+ 250, 251, 250, 251, 250, 251, 250, 251,
+
+ 250, 251, 250, 251, 250, 251, 250, 251,
+ 250, 251, 250, 251, 250, 251, 250, 251,
+ 250, 251, 250, 251, 250, 251, 250, 251,
+ 250, 251, 250, 251, 250, 251, 250, 251,
+
+ 262, 252, 253, 250, 251, 258, 259, 250,
+ 251, 258, 259, 250, 251, 258, 259, 263,
+ 252, 253, 252, 253, 250, 251, 252, 253,
+ 250, 251, 252, 253, 252, 253, 252, 253,
+
+ 250, 251, 252, 253, 252, 253, 252, 253,
+ 250, 251, 252, 253, 264, 265, 252, 253,
+ 252, 253, 252, 253, 252, 253, 266, 267,
+ 252, 253, 268, 269, 268, 269, 268, 269,
+
+ 258, 259, 258, 259, 258, 259, 258, 259,
+ 258, 259, 258, 259, 258, 259, 258, 259,
+ 268, 269, 268, 269, 270, 271, 270, 271,
+ 270, 271, 270, 271, 270, 271, 270, 271,
+
+ 270, 271, 270, 271, 272, 273, 274, 275,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276,
+
+ 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 192,
+ 192, 277, 278, 278, 279, 280, 279, 278,
+
+ 192, 281, 281, 281, 281, 281, 281, 281,
+ 281, 281, 281, 281, 281, 281, 281, 281,
+ 281, 281, 281, 281, 281, 281, 281, 281,
+ 281, 281, 281, 281, 281, 281, 281, 281,
+
+ 281, 281, 281, 281, 281, 281, 281, 282,
+ 192, 283, 284, 192, 192, 192, 192, 285,
+ 286, 287, 288, 288, 288, 288, 287, 288,
+ 288, 288, 289, 287, 288, 288, 288, 288,
+
+ 288, 288, 290, 287, 287, 287, 287, 287,
+ 288, 288, 287, 288, 288, 289, 291, 288,
+ 292, 293, 294, 295, 296, 297, 298, 299,
+ 300, 301, 302, 303, 304, 305, 306, 307,
+
+ 308, 309, 310, 308, 288, 290, 311, 312,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 313, 313, 313, 313, 313, 313, 313, 313,
+ 313, 313, 313, 313, 313, 313, 313, 313,
+
+ 313, 313, 313, 313, 313, 313, 313, 313,
+ 313, 313, 313, 286, 286, 286, 286, 286,
+ 313, 313, 313, 314, 315, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+
+ 316, 316, 316, 316, 317, 318, 319, 319,
+ 320, 321, 321, 322, 19, 323, 324, 324,
+ 325, 325, 325, 325, 325, 325, 326, 326,
+ 327, 328, 329, 330, 318, 318, 331, 332,
+
+ 333, 334, 335, 335, 335, 335, 336, 337,
+ 338, 337, 338, 338, 338, 338, 338, 337,
+ 337, 337, 337, 338, 338, 338, 338, 338,
+ 338, 338, 338, 339, 339, 339, 339, 339,
+
+ 340, 338, 338, 338, 338, 338, 338, 338,
+ 337, 338, 338, 341, 342, 343, 344, 345,
+ 346, 347, 348, 349, 349, 350, 351, 325,
+ 325, 352, 352, 352, 353, 352, 352, 354,
+
+ 355, 356, 357, 358, 359, 360, 361, 362,
+ 363, 364, 365, 366, 367, 368, 369, 369,
+ 370, 337, 337, 337, 334, 371, 371, 371,
+ 372, 338, 338, 338, 338, 338, 338, 338,
+
+ 338, 338, 338, 338, 338, 338, 338, 338,
+ 337, 337, 337, 337, 337, 337, 337, 337,
+ 337, 337, 337, 337, 337, 337, 337, 337,
+ 337, 337, 338, 338, 338, 338, 338, 338,
+
+ 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338,
+ 373, 373, 338, 338, 338, 338, 338, 373,
+
+ 335, 338, 336, 337, 337, 337, 337, 337,
+ 337, 337, 337, 337, 338, 337, 338, 374,
+ 338, 338, 337, 335, 375, 337, 376, 376,
+ 376, 376, 376, 376, 376, 377, 378, 376,
+
+ 376, 376, 376, 379, 376, 380, 380, 376,
+ 376, 378, 379, 376, 376, 379, 381, 381,
+ 382, 383, 384, 385, 386, 387, 388, 389,
+ 390, 391, 373, 373, 373, 392, 392, 393,
+
+ 394, 394, 394, 395, 395, 395, 395, 395,
+ 395, 395, 395, 395, 395, 395, 318, 396,
+ 397, 398, 399, 399, 399, 397, 397, 397,
+ 397, 397, 399, 399, 399, 399, 397, 399,
+
+ 399, 399, 399, 399, 399, 399, 399, 399,
+ 397, 399, 397, 399, 397, 400, 400, 401,
+ 402, 403, 402, 402, 403, 402, 402, 403,
+ 403, 403, 402, 403, 403, 402, 403, 402,
+
+ 402, 402, 403, 402, 403, 402, 403, 402,
+ 403, 402, 402, 318, 318, 401, 400, 400,
+ 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 405, 405, 405, 404, 404, 404, 404,
+
+ 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 404, 404, 405, 405, 404, 339, 339,
+ 339, 406, 339, 406, 406, 339, 339, 339,
+ 406, 406, 339, 339, 339, 339, 339, 339,
+
+ 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 408, 408,
+ 408, 408, 408, 408, 408, 408, 408, 408,
+ 408, 409, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+
+ 410, 411, 412, 413, 414, 415, 416, 417,
+ 418, 419, 420, 420, 420, 420, 420, 420,
+ 420, 420, 420, 420, 420, 420, 420, 420,
+ 420, 420, 420, 420, 420, 420, 420, 420,
+
+ 420, 420, 420, 420, 420, 420, 420, 420,
+ 420, 420, 420, 421, 421, 421, 421, 421,
+ 421, 421, 422, 421, 423, 423, 424, 425,
+ 426, 427, 428, 286, 286, 286, 286, 286,
+
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 430, 430,
+ 430, 430, 431, 430, 430, 430, 430, 430,
+
+ 430, 430, 430, 430, 431, 430, 430, 430,
+ 431, 430, 430, 430, 430, 430, 286, 286,
+ 432, 432, 432, 432, 432, 432, 432, 432,
+ 432, 432, 432, 432, 432, 432, 432, 286,
+
+ 433, 434, 434, 434, 434, 434, 433, 434,
+ 434, 433, 434, 434, 434, 434, 434, 433,
+ 434, 434, 434, 434, 433, 434, 435, 435,
+ 435, 436, 436, 436, 286, 286, 437, 286,
+
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+
+ 438, 318, 438, 438, 438, 438, 438, 438,
+ 438, 438, 439, 439, 439, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+
+ 318, 318, 318, 318, 440, 440, 441, 440,
+ 440, 441, 440, 440, 440, 441, 441, 441,
+ 442, 443, 444, 440, 440, 440, 441, 440,
+ 440, 441, 441, 440, 440, 440, 440, 318,
+
+ 445, 446, 446, 447, 448, 449, 449, 449,
+ 449, 449, 449, 449, 449, 449, 449, 449,
+ 449, 449, 449, 449, 449, 449, 449, 449,
+ 449, 449, 449, 449, 449, 449, 449, 449,
+
+ 449, 449, 449, 449, 449, 449, 449, 449,
+ 449, 450, 449, 449, 449, 449, 449, 449,
+ 449, 450, 449, 449, 450, 449, 449, 449,
+ 449, 449, 451, 452, 453, 449, 447, 447,
+
+ 447, 446, 446, 446, 446, 446, 446, 446,
+ 446, 447, 447, 447, 447, 454, 455, 452,
+ 449, 163, 165, 456, 456, 445, 451, 451,
+ 457, 457, 457, 457, 457, 457, 457, 457,
+
+ 449, 449, 446, 446, 458, 458, 459, 460,
+ 461, 462, 463, 464, 465, 466, 467, 468,
+ 469, 470, 471, 472, 472, 472, 472, 472,
+ 192, 473, 473, 474, 474, 475, 474, 474,
+
+ 192, 476, 477, 477, 192, 478, 478, 478,
+ 478, 478, 478, 478, 478, 192, 192, 478,
+ 478, 192, 192, 478, 478, 478, 478, 478,
+ 478, 478, 478, 478, 478, 478, 478, 478,
+
+ 478, 478, 478, 478, 478, 478, 478, 478,
+ 478, 192, 478, 478, 478, 478, 478, 478,
+ 478, 192, 478, 192, 192, 192, 478, 478,
+ 478, 478, 192, 192, 479, 480, 481, 477,
+
+ 477, 476, 476, 476, 476, 192, 192, 477,
+ 477, 192, 192, 482, 482, 483, 484, 192,
+ 192, 192, 192, 192, 192, 192, 192, 481,
+ 192, 192, 192, 192, 485, 485, 192, 485,
+
+ 478, 478, 476, 476, 192, 192, 486, 487,
488, 489, 490, 491, 492, 493, 494, 495,
- 496, 497, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 498, 499, 499, 177, 500, 500, 500,
- 500, 500, 500, 500, 500, 177, 177, 500,
- 500, 177, 177, 500, 500, 500, 500, 500,
- 500, 500, 500, 500, 500, 500, 500, 500,
-
- 500, 500, 500, 500, 500, 500, 500, 500,
- 500, 177, 500, 500, 500, 500, 500, 500,
- 500, 177, 500, 500, 177, 501, 500, 500,
- 500, 500, 177, 177, 502, 500, 503, 498,
-
- 499, 498, 498, 498, 504, 177, 177, 499,
- 499, 177, 177, 499, 499, 505, 177, 177,
- 177, 177, 177, 177, 177, 177, 498, 503,
- 177, 177, 177, 177, 500, 500, 177, 500,
-
- 500, 500, 504, 504, 177, 177, 506, 507,
- 508, 509, 510, 511, 512, 513, 514, 515,
- 516, 501, 517, 517, 517, 517, 517, 517,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 518, 519, 177, 519, 519, 519,
- 519, 519, 519, 177, 177, 177, 519, 519,
- 519, 177, 519, 519, 519, 519, 177, 177,
- 177, 519, 519, 177, 519, 177, 519, 519,
-
- 177, 177, 177, 519, 519, 177, 177, 177,
- 519, 519, 519, 177, 177, 177, 519, 519,
- 519, 519, 519, 519, 519, 519, 520, 519,
- 519, 519, 177, 177, 177, 177, 521, 522,
-
- 518, 522, 522, 177, 177, 177, 522, 522,
- 522, 177, 522, 522, 522, 523, 177, 177,
- 524, 177, 177, 177, 177, 177, 177, 521,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 525, 526,
- 527, 528, 529, 530, 531, 532, 533, 534,
- 535, 535, 535, 536, 536, 536, 536, 536,
- 536, 537, 536, 177, 177, 177, 177, 177,
-
- 177, 538, 538, 538, 177, 539, 539, 539,
- 539, 539, 539, 539, 539, 177, 539, 539,
- 539, 177, 539, 539, 539, 539, 539, 539,
- 539, 539, 539, 539, 539, 539, 539, 539,
-
- 539, 539, 539, 539, 539, 539, 539, 539,
- 539, 177, 539, 539, 539, 539, 539, 539,
- 539, 539, 539, 539, 177, 539, 539, 539,
- 539, 539, 177, 177, 177, 540, 541, 541,
-
- 541, 538, 538, 538, 538, 177, 541, 541,
- 541, 177, 541, 541, 541, 542, 177, 177,
- 177, 177, 177, 177, 177, 543, 544, 177,
- 540, 540, 177, 177, 177, 177, 177, 177,
-
- 539, 539, 545, 545, 177, 177, 546, 547,
- 548, 549, 550, 551, 552, 553, 554, 555,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 556, 556, 556, 556, 556, 556, 556, 557,
-
- 177, 177, 558, 558, 177, 559, 559, 559,
- 559, 559, 559, 559, 559, 177, 559, 559,
- 559, 177, 559, 559, 559, 559, 559, 559,
- 559, 559, 559, 559, 559, 559, 559, 559,
-
- 559, 559, 559, 559, 559, 559, 559, 559,
- 559, 177, 559, 559, 559, 559, 559, 559,
- 559, 559, 559, 559, 177, 559, 559, 559,
- 559, 559, 177, 177, 560, 561, 558, 562,
-
- 558, 558, 563, 558, 558, 177, 562, 558,
- 558, 177, 558, 558, 564, 565, 177, 177,
- 177, 177, 177, 177, 177, 563, 563, 177,
- 177, 177, 177, 177, 177, 177, 559, 177,
-
- 559, 559, 566, 566, 177, 177, 567, 568,
- 569, 570, 571, 572, 573, 574, 575, 576,
- 177, 577, 577, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 578, 578, 177, 579, 579, 579,
- 579, 579, 579, 579, 579, 177, 579, 579,
- 579, 177, 579, 579, 579, 579, 579, 579,
- 579, 579, 579, 579, 579, 579, 579, 579,
-
- 579, 579, 579, 579, 579, 579, 579, 579,
- 579, 580, 579, 579, 579, 579, 579, 579,
- 579, 579, 579, 579, 579, 579, 579, 579,
- 579, 579, 580, 177, 177, 581, 582, 578,
-
- 578, 583, 583, 583, 584, 177, 578, 578,
- 578, 177, 578, 578, 578, 585, 580, 177,
- 177, 177, 177, 177, 177, 177, 177, 582,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 579, 579, 584, 584, 177, 177, 586, 587,
- 588, 589, 590, 591, 592, 593, 594, 595,
- 596, 596, 596, 596, 596, 596, 177, 177,
- 177, 597, 581, 581, 581, 581, 581, 581,
-
- 177, 177, 598, 598, 177, 599, 599, 599,
- 599, 599, 599, 599, 599, 599, 599, 599,
- 599, 599, 599, 599, 599, 599, 599, 177,
- 177, 177, 599, 599, 599, 599, 599, 599,
-
- 599, 599, 599, 599, 599, 599, 599, 599,
- 599, 599, 599, 599, 599, 599, 599, 599,
- 599, 599, 177, 599, 599, 599, 599, 599,
- 599, 599, 599, 599, 177, 599, 177, 177,
-
- 599, 599, 599, 599, 599, 599, 599, 177,
- 177, 177, 600, 177, 177, 177, 177, 601,
- 598, 598, 602, 602, 602, 177, 602, 177,
- 598, 598, 598, 598, 598, 598, 598, 601,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 598, 598, 603, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 604, 604, 604, 604, 604, 604, 604,
- 604, 604, 604, 604, 604, 604, 604, 604,
- 604, 604, 604, 604, 604, 604, 604, 604,
- 604, 604, 604, 604, 604, 604, 604, 604,
-
- 604, 604, 604, 604, 604, 604, 604, 604,
- 604, 604, 604, 604, 604, 604, 604, 604,
- 604, 605, 604, 606, 605, 605, 605, 605,
- 607, 607, 608, 177, 177, 177, 177, 12,
-
- 604, 604, 604, 604, 604, 604, 609, 605,
- 610, 610, 610, 610, 605, 605, 605, 611,
- 612, 613, 614, 615, 616, 617, 618, 619,
- 620, 621, 622, 622, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 623, 623, 177, 623, 177, 177, 623,
- 623, 177, 623, 177, 177, 623, 177, 177,
- 177, 177, 177, 177, 623, 623, 623, 623,
- 177, 623, 623, 623, 623, 623, 623, 623,
-
- 177, 623, 623, 623, 177, 623, 177, 623,
- 177, 177, 623, 623, 177, 623, 623, 623,
- 623, 624, 623, 625, 624, 624, 624, 624,
- 626, 626, 177, 624, 624, 623, 177, 177,
-
- 623, 623, 623, 623, 623, 177, 627, 177,
- 628, 628, 628, 628, 624, 624, 177, 177,
- 629, 630, 631, 632, 633, 634, 635, 636,
- 637, 638, 177, 177, 623, 623, 639, 639,
-
- 640, 641, 641, 641, 642, 643, 642, 642,
- 644, 642, 642, 645, 644, 646, 646, 646,
- 646, 646, 644, 647, 646, 647, 647, 647,
- 648, 648, 647, 647, 647, 647, 647, 647,
-
- 649, 650, 651, 652, 653, 654, 655, 656,
- 657, 658, 659, 659, 659, 659, 659, 659,
- 659, 659, 659, 659, 660, 648, 647, 648,
- 647, 661, 662, 663, 662, 663, 664, 664,
-
- 640, 640, 640, 640, 640, 640, 640, 640,
- 177, 640, 640, 640, 640, 640, 640, 640,
- 640, 640, 640, 640, 640, 640, 640, 640,
- 640, 640, 640, 640, 640, 640, 640, 640,
-
- 640, 640, 640, 640, 640, 640, 640, 640,
- 640, 640, 665, 666, 666, 177, 177, 177,
- 177, 667, 668, 669, 670, 669, 669, 669,
- 669, 669, 668, 668, 668, 668, 669, 671,
-
- 668, 669, 672, 672, 673, 645, 672, 672,
- 640, 640, 640, 640, 674, 675, 675, 675,
- 669, 669, 669, 669, 669, 669, 676, 669,
- 177, 669, 669, 669, 669, 669, 669, 669,
-
- 669, 669, 669, 669, 669, 669, 669, 669,
- 669, 669, 669, 669, 669, 669, 676, 676,
- 676, 669, 669, 669, 669, 669, 669, 669,
- 676, 669, 676, 676, 676, 177, 677, 677,
-
- 678, 678, 678, 678, 678, 678, 679, 678,
- 678, 678, 678, 678, 678, 177, 680, 678,
- 681, 681, 682, 683, 684, 685, 685, 685,
- 685, 686, 686, 177, 177, 177, 177, 177,
-
- 687, 687, 687, 687, 687, 687, 687, 687,
- 687, 687, 687, 687, 687, 687, 687, 687,
- 687, 687, 687, 687, 687, 687, 687, 687,
- 687, 687, 687, 687, 687, 687, 687, 687,
-
- 687, 687, 688, 687, 687, 687, 687, 687,
- 688, 687, 687, 689, 690, 691, 691, 691,
- 691, 692, 691, 693, 693, 693, 691, 694,
- 690, 695, 696, 697, 697, 693, 693, 688,
-
- 698, 699, 700, 701, 702, 703, 704, 705,
- 706, 707, 708, 708, 709, 709, 709, 709,
- 687, 687, 687, 687, 687, 687, 692, 692,
- 691, 691, 688, 688, 688, 688, 693, 693,
-
- 693, 688, 689, 689, 689, 688, 688, 689,
- 689, 689, 689, 689, 689, 689, 688, 688,
- 688, 693, 693, 693, 693, 688, 688, 688,
- 688, 688, 688, 688, 688, 688, 688, 688,
-
- 688, 688, 693, 689, 697, 693, 693, 689,
- 689, 689, 689, 689, 689, 710, 688, 689,
- 711, 712, 713, 714, 715, 716, 717, 718,
- 719, 720, 721, 721, 721, 722, 723, 723,
-
- 724, 724, 724, 724, 724, 724, 724, 724,
- 724, 724, 724, 724, 724, 724, 724, 724,
- 724, 724, 724, 724, 724, 724, 724, 724,
- 724, 724, 724, 724, 724, 724, 724, 724,
-
- 724, 724, 724, 724, 724, 724, 177, 725,
- 177, 177, 177, 177, 177, 725, 177, 177,
- 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, 726, 727,
- 727, 728, 728, 729, 730, 731, 731, 731,
-
- 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, 732, 733, 733, 733, 733, 733, 732,
-
- 734, 734, 734, 734, 734, 734, 734, 734,
- 734, 734, 734, 734, 734, 734, 734, 734,
- 734, 734, 734, 734, 734, 734, 734, 734,
- 734, 734, 734, 734, 734, 734, 734, 734,
-
- 734, 734, 734, 735, 735, 735, 735, 735,
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736,
-
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736,
-
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, 737, 737, 737, 737, 737, 737,
-
- 738, 738, 738, 738, 738, 738, 738, 739,
- 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, 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, 739,
- 738, 177, 738, 738, 738, 738, 177, 177,
- 738, 738, 738, 738, 738, 738, 738, 177,
- 738, 177, 738, 738, 738, 738, 177, 177,
-
- 738, 738, 738, 738, 738, 738, 738, 739,
- 738, 177, 738, 738, 738, 738, 177, 177,
- 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, 739,
- 738, 177, 738, 738, 738, 738, 177, 177,
- 738, 738, 738, 738, 738, 738, 738, 177,
-
- 738, 177, 738, 738, 738, 738, 177, 177,
- 738, 738, 738, 738, 738, 738, 738, 739,
- 738, 738, 738, 738, 738, 738, 738, 177,
- 738, 738, 738, 738, 738, 738, 738, 738,
-
- 738, 738, 738, 738, 738, 738, 738, 738,
- 738, 738, 738, 738, 738, 738, 738, 739,
- 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, 739,
- 738, 177, 738, 738, 738, 738, 177, 177,
- 738, 738, 738, 738, 738, 738, 738, 739,
-
- 738, 738, 738, 738, 738, 738, 738, 739,
- 738, 738, 738, 738, 738, 738, 738, 738,
- 738, 738, 738, 738, 738, 738, 738, 738,
- 738, 738, 738, 177, 177, 740, 740, 741,
-
- 742, 743, 744, 745, 745, 745, 745, 744,
- 744, 746, 747, 748, 749, 750, 751, 752,
- 753, 754, 755, 755, 755, 755, 755, 755,
- 755, 755, 755, 755, 755, 177, 177, 177,
-
- 739, 739, 739, 739, 739, 739, 739, 739,
- 739, 739, 739, 739, 739, 739, 739, 739,
- 756, 756, 756, 756, 756, 756, 756, 756,
- 756, 756, 177, 177, 177, 177, 177, 177,
-
- 757, 757, 757, 757, 757, 757, 757, 757,
- 757, 757, 757, 757, 757, 757, 757, 757,
- 757, 757, 757, 757, 757, 757, 757, 757,
- 757, 757, 757, 757, 757, 757, 757, 757,
-
- 757, 757, 757, 757, 757, 757, 757, 757,
- 757, 757, 757, 757, 757, 757, 757, 757,
- 757, 757, 757, 757, 757, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 758, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, 759, 759, 759, 759, 759,
-
- 759, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, 759, 759, 759, 759, 759,
-
- 759, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, 759, 759, 760, 761, 759,
- 759, 759, 759, 759, 759, 759, 759, 762,
- 762, 762, 762, 762, 762, 762, 762, 762,
-
- 763, 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, 765, 766, 177, 177, 177,
-
- 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, 768, 768, 768, 769, 769,
- 769, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 770, 770, 770, 770, 770, 770, 770, 770,
- 770, 770, 770, 770, 770, 177, 770, 770,
- 770, 770, 771, 771, 772, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 773, 773, 773, 773, 773, 773, 773, 773,
- 773, 773, 773, 773, 773, 773, 773, 773,
- 773, 773, 774, 774, 775, 776, 776, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 777, 777, 777, 777, 777, 777, 777, 777,
- 777, 777, 777, 777, 777, 777, 777, 777,
- 777, 777, 778, 778, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 779, 779, 779, 779, 779, 779, 779, 779,
- 779, 779, 779, 779, 779, 177, 779, 779,
- 779, 177, 780, 780, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
+ 478, 478, 496, 496, 497, 497, 497, 497,
+ 497, 498, 499, 500, 192, 192, 192, 192,
+
+ 192, 501, 502, 503, 192, 504, 504, 504,
+ 504, 504, 504, 192, 192, 192, 192, 504,
+ 504, 192, 192, 504, 504, 504, 504, 504,
+ 504, 504, 504, 504, 504, 504, 504, 504,
+
+ 504, 504, 504, 504, 504, 504, 504, 504,
+ 504, 192, 504, 504, 504, 504, 504, 504,
+ 504, 192, 504, 505, 192, 504, 505, 192,
+ 504, 504, 192, 192, 506, 192, 507, 507,
+
+ 507, 502, 502, 192, 192, 192, 192, 502,
+ 502, 192, 192, 502, 502, 508, 192, 192,
+ 192, 509, 192, 192, 192, 192, 192, 192,
+ 192, 505, 505, 505, 504, 192, 505, 192,
+
+ 192, 192, 192, 192, 192, 192, 510, 511,
+ 512, 513, 514, 515, 516, 517, 518, 519,
+ 502, 502, 504, 504, 504, 509, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 520, 520, 521, 192, 522, 522, 522,
+ 522, 522, 522, 522, 523, 522, 192, 522,
+ 522, 522, 192, 522, 522, 522, 522, 522,
+ 522, 522, 522, 522, 522, 522, 522, 522,
+
+ 522, 522, 522, 522, 522, 522, 522, 522,
+ 522, 192, 522, 522, 522, 522, 522, 522,
+ 522, 192, 522, 522, 192, 522, 522, 522,
+ 522, 522, 192, 192, 524, 522, 521, 521,
+
+ 521, 520, 520, 520, 520, 520, 192, 520,
+ 520, 521, 192, 521, 521, 525, 192, 192,
+ 522, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 522, 523, 526, 526, 192, 192, 527, 528,
+ 529, 530, 531, 532, 533, 534, 535, 536,
+ 537, 538, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 539, 540, 540, 192, 541, 541, 541,
+ 541, 541, 541, 541, 541, 192, 192, 541,
+ 541, 192, 192, 541, 541, 541, 541, 541,
+ 541, 541, 541, 541, 541, 541, 541, 541,
+
+ 541, 541, 541, 541, 541, 541, 541, 541,
+ 541, 192, 541, 541, 541, 541, 541, 541,
+ 541, 192, 541, 541, 192, 542, 541, 541,
+ 541, 541, 192, 192, 543, 541, 544, 539,
+
+ 540, 539, 539, 539, 545, 192, 192, 540,
+ 546, 192, 192, 546, 546, 547, 192, 192,
+ 192, 192, 192, 192, 192, 192, 548, 544,
+ 192, 192, 192, 192, 549, 549, 192, 541,
+
+ 541, 541, 545, 545, 192, 192, 550, 551,
+ 552, 553, 554, 555, 556, 557, 558, 559,
+ 560, 542, 561, 561, 561, 561, 561, 561,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 562, 563, 192, 563, 563, 563,
+ 563, 563, 563, 192, 192, 192, 563, 563,
+ 563, 192, 563, 563, 564, 563, 192, 192,
+ 192, 563, 563, 192, 563, 192, 563, 563,
+
+ 192, 192, 192, 563, 563, 192, 192, 192,
+ 563, 563, 563, 192, 192, 192, 563, 563,
+ 563, 563, 563, 563, 563, 563, 565, 563,
+ 563, 563, 192, 192, 192, 192, 566, 567,
+
+ 562, 567, 567, 192, 192, 192, 567, 567,
+ 567, 192, 568, 568, 568, 569, 192, 192,
+ 570, 192, 192, 192, 192, 192, 192, 566,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 571, 572,
+ 573, 574, 575, 576, 577, 578, 579, 580,
+ 581, 581, 581, 582, 582, 582, 582, 582,
+ 582, 583, 582, 192, 192, 192, 192, 192,
+
+ 192, 584, 584, 584, 192, 585, 585, 585,
+ 585, 585, 585, 585, 585, 192, 585, 585,
+ 585, 192, 585, 585, 585, 585, 585, 585,
+ 585, 585, 585, 585, 585, 585, 585, 585,
+
+ 585, 585, 585, 585, 585, 585, 585, 585,
+ 585, 192, 585, 585, 585, 585, 585, 585,
+ 585, 585, 585, 585, 192, 585, 585, 585,
+ 585, 585, 192, 192, 192, 586, 587, 587,
+
+ 587, 584, 584, 584, 584, 192, 587, 587,
+ 588, 192, 587, 587, 587, 589, 192, 192,
+ 192, 192, 192, 192, 192, 590, 591, 192,
+ 586, 586, 192, 192, 192, 192, 192, 192,
+
+ 585, 585, 592, 592, 192, 192, 593, 594,
+ 595, 596, 597, 598, 599, 600, 601, 602,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 603, 603, 603, 603, 603, 603, 603, 604,
+
+ 192, 192, 605, 605, 192, 606, 606, 606,
+ 606, 606, 606, 606, 606, 192, 606, 606,
+ 606, 192, 606, 606, 606, 606, 606, 606,
+ 606, 606, 606, 606, 606, 606, 606, 606,
+
+ 606, 606, 606, 606, 606, 606, 606, 606,
+ 606, 192, 606, 606, 606, 606, 606, 606,
+ 606, 606, 606, 606, 192, 606, 606, 606,
+ 606, 606, 192, 192, 607, 608, 605, 609,
+
+ 610, 605, 611, 605, 605, 192, 609, 610,
+ 610, 192, 610, 610, 612, 613, 192, 192,
+ 192, 192, 192, 192, 192, 611, 611, 192,
+ 192, 192, 192, 192, 192, 192, 606, 192,
+
+ 606, 606, 614, 614, 192, 192, 615, 616,
+ 617, 618, 619, 620, 621, 622, 623, 624,
+ 192, 625, 625, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 626, 626, 192, 627, 627, 627,
+ 627, 627, 627, 627, 627, 192, 627, 627,
+ 627, 192, 627, 627, 627, 627, 627, 627,
+ 627, 627, 627, 627, 627, 627, 627, 627,
+
+ 627, 627, 627, 627, 627, 627, 627, 627,
+ 627, 628, 627, 627, 627, 627, 627, 627,
+ 627, 627, 627, 627, 627, 627, 627, 627,
+ 627, 627, 628, 192, 192, 629, 630, 626,
+
+ 626, 631, 631, 631, 632, 192, 626, 626,
+ 626, 192, 633, 633, 633, 634, 628, 192,
+ 192, 192, 192, 192, 192, 192, 192, 630,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 627, 627, 632, 632, 192, 192, 635, 636,
+ 637, 638, 639, 640, 641, 642, 643, 644,
+ 645, 645, 645, 645, 645, 645, 192, 192,
+ 192, 646, 629, 629, 629, 629, 629, 629,
+
+ 192, 192, 647, 647, 192, 648, 648, 648,
+ 648, 648, 648, 648, 648, 648, 648, 648,
+ 648, 648, 648, 648, 648, 648, 648, 192,
+ 192, 192, 648, 648, 648, 648, 648, 648,
+
+ 648, 648, 648, 648, 648, 648, 648, 648,
+ 648, 648, 648, 648, 648, 648, 648, 648,
+ 648, 648, 192, 648, 648, 648, 648, 648,
+ 648, 648, 648, 648, 192, 648, 192, 192,
+
+ 648, 648, 648, 648, 648, 648, 648, 192,
+ 192, 192, 649, 192, 192, 192, 192, 650,
+ 647, 647, 651, 651, 651, 192, 651, 192,
+ 647, 647, 652, 647, 652, 652, 652, 650,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 647, 647, 653, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 654, 654, 654, 654, 654, 654, 654,
+ 654, 654, 654, 654, 654, 654, 654, 654,
+ 654, 654, 654, 654, 654, 654, 654, 654,
+ 654, 654, 654, 654, 654, 654, 654, 654,
+
+ 654, 654, 654, 654, 654, 654, 654, 654,
+ 654, 654, 654, 654, 654, 654, 654, 654,
+ 654, 655, 654, 656, 655, 655, 655, 655,
+ 657, 657, 658, 192, 192, 192, 192, 12,
+
+ 654, 654, 654, 654, 654, 654, 659, 655,
+ 660, 660, 660, 660, 655, 655, 655, 661,
+ 662, 663, 664, 665, 666, 667, 668, 669,
+ 670, 671, 672, 672, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 673, 673, 192, 673, 192, 192, 673,
+ 673, 192, 673, 192, 192, 673, 192, 192,
+ 192, 192, 192, 192, 673, 673, 673, 673,
+ 192, 673, 673, 673, 673, 673, 673, 673,
+
+ 192, 673, 673, 673, 192, 673, 192, 673,
+ 192, 192, 673, 673, 192, 673, 673, 673,
+ 673, 674, 673, 675, 674, 674, 674, 674,
+ 676, 676, 192, 674, 674, 673, 192, 192,
+
+ 673, 673, 673, 673, 673, 192, 677, 192,
+ 678, 678, 678, 678, 674, 674, 192, 192,
+ 679, 680, 681, 682, 683, 684, 685, 686,
+ 687, 688, 192, 192, 689, 689, 690, 690,
+
+ 691, 692, 692, 692, 693, 694, 693, 693,
+ 695, 693, 693, 696, 697, 698, 698, 698,
+ 698, 698, 695, 699, 698, 699, 699, 699,
+ 700, 700, 699, 699, 699, 699, 699, 699,
+
+ 701, 702, 703, 704, 705, 706, 707, 708,
+ 709, 710, 711, 711, 711, 711, 711, 711,
+ 711, 711, 711, 711, 712, 700, 699, 700,
+ 699, 713, 714, 715, 714, 715, 716, 716,
+
+ 691, 691, 691, 717, 691, 691, 691, 691,
+ 192, 691, 691, 691, 691, 717, 691, 691,
+ 691, 691, 717, 691, 691, 691, 691, 717,
+ 691, 691, 691, 691, 717, 691, 691, 691,
+
+ 691, 691, 691, 691, 691, 691, 691, 691,
+ 691, 717, 718, 719, 719, 192, 192, 192,
+ 192, 720, 721, 722, 723, 722, 722, 724,
+ 722, 724, 721, 721, 721, 721, 725, 726,
+
+ 721, 722, 727, 727, 728, 696, 727, 727,
+ 691, 691, 691, 691, 729, 730, 730, 730,
+ 725, 725, 725, 722, 725, 725, 731, 725,
+ 192, 725, 725, 725, 725, 722, 725, 725,
+
+ 725, 725, 722, 725, 725, 725, 725, 722,
+ 725, 725, 725, 725, 722, 725, 731, 731,
+ 731, 725, 725, 725, 725, 725, 725, 725,
+ 731, 722, 731, 731, 731, 192, 732, 732,
+
+ 733, 733, 733, 733, 733, 733, 734, 733,
+ 733, 733, 733, 733, 733, 192, 735, 733,
+ 736, 736, 737, 738, 739, 740, 740, 740,
+ 740, 741, 741, 192, 192, 192, 192, 192,
+
+ 742, 742, 742, 742, 742, 742, 742, 742,
+ 742, 742, 742, 742, 742, 742, 742, 742,
+ 742, 742, 742, 742, 742, 742, 742, 742,
+ 742, 742, 742, 742, 742, 742, 742, 742,
+
+ 742, 742, 743, 742, 742, 742, 744, 742,
+ 743, 742, 742, 745, 746, 747, 748, 747,
+ 747, 749, 747, 750, 750, 750, 747, 751,
+ 746, 752, 753, 754, 754, 750, 750, 743,
+
+ 755, 756, 757, 758, 759, 760, 761, 762,
+ 763, 764, 765, 765, 766, 766, 766, 766,
+ 742, 742, 742, 742, 742, 742, 749, 749,
+ 747, 747, 743, 743, 743, 743, 750, 750,
+
+ 750, 743, 745, 745, 745, 743, 743, 745,
+ 745, 745, 745, 745, 745, 745, 743, 743,
+ 743, 750, 750, 750, 750, 743, 743, 743,
+ 743, 743, 743, 743, 743, 743, 743, 743,
+
+ 743, 743, 750, 745, 754, 750, 750, 745,
+ 745, 745, 745, 745, 745, 767, 743, 745,
+ 768, 769, 770, 771, 772, 773, 774, 775,
+ 776, 777, 778, 778, 778, 779, 780, 780,
781, 781, 781, 781, 781, 781, 781, 781,
781, 781, 781, 781, 781, 781, 781, 781,
781, 781, 781, 781, 781, 781, 781, 781,
781, 781, 781, 781, 781, 781, 781, 781,
- 781, 781, 781, 781, 781, 781, 781, 781,
- 781, 781, 781, 781, 781, 781, 781, 781,
- 781, 781, 781, 781, 782, 782, 783, 782,
- 782, 782, 782, 782, 782, 782, 783, 783,
-
- 783, 783, 783, 783, 783, 783, 782, 783,
- 783, 782, 782, 782, 782, 782, 782, 782,
- 782, 782, 784, 782, 785, 785, 786, 787,
- 785, 788, 785, 789, 781, 790, 177, 177,
-
- 791, 792, 793, 794, 795, 796, 797, 798,
- 799, 800, 177, 177, 177, 177, 177, 177,
- 801, 801, 801, 801, 801, 801, 801, 801,
- 801, 801, 177, 177, 177, 177, 177, 177,
-
- 802, 802, 803, 804, 805, 806, 807, 802,
- 808, 809, 802, 810, 810, 810, 811, 177,
- 812, 813, 814, 815, 816, 817, 818, 819,
- 820, 821, 177, 177, 177, 177, 177, 177,
-
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
-
- 822, 822, 822, 823, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
-
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 822, 822,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 822, 822, 822, 822, 822, 822, 822, 822,
- 822, 824, 825, 177, 177, 177, 177, 177,
- 762, 762, 762, 762, 762, 762, 762, 762,
- 762, 762, 762, 762, 762, 762, 762, 762,
-
- 762, 762, 762, 762, 762, 762, 762, 762,
- 762, 762, 762, 762, 762, 762, 762, 762,
- 762, 762, 762, 762, 762, 762, 762, 762,
- 762, 762, 762, 762, 762, 762, 762, 762,
-
- 762, 762, 762, 762, 762, 762, 762, 762,
- 762, 762, 762, 762, 762, 762, 762, 762,
- 762, 762, 762, 762, 762, 762, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
+ 781, 781, 781, 781, 781, 781, 192, 782,
+ 192, 192, 192, 192, 192, 782, 192, 192,
+ 783, 783, 783, 783, 783, 783, 783, 783,
+ 783, 783, 783, 783, 783, 783, 783, 783,
+
+ 783, 783, 783, 783, 783, 783, 783, 783,
+ 783, 783, 783, 783, 783, 783, 783, 783,
+ 783, 783, 783, 783, 783, 783, 783, 784,
+ 784, 785, 785, 786, 787, 788, 788, 788,
+
+ 789, 789, 789, 789, 789, 789, 789, 789,
+ 789, 789, 789, 789, 789, 789, 789, 789,
+ 789, 789, 789, 789, 789, 789, 789, 789,
+ 789, 789, 789, 789, 789, 789, 789, 789,
+
+ 789, 789, 789, 789, 789, 789, 789, 789,
+ 789, 789, 789, 789, 789, 789, 789, 789,
+ 789, 789, 789, 789, 789, 789, 789, 789,
+ 789, 789, 790, 790, 790, 790, 790, 789,
+
+ 791, 792, 792, 792, 792, 792, 792, 792,
+ 792, 792, 792, 792, 792, 792, 792, 792,
+ 792, 792, 792, 792, 792, 792, 791, 791,
+ 791, 791, 791, 791, 791, 791, 791, 791,
+
+ 791, 791, 791, 791, 791, 791, 791, 791,
+ 791, 791, 791, 791, 791, 791, 791, 791,
+ 791, 791, 791, 791, 791, 791, 791, 791,
+ 791, 791, 791, 791, 791, 791, 791, 791,
+
+ 791, 791, 791, 793, 793, 793, 793, 793,
+ 794, 794, 794, 794, 794, 794, 794, 794,
+ 794, 794, 794, 794, 794, 794, 794, 794,
+ 794, 794, 794, 794, 794, 794, 794, 794,
+
+ 794, 794, 794, 795, 795, 795, 795, 795,
+ 795, 795, 795, 795, 795, 795, 795, 795,
+ 795, 795, 795, 795, 795, 795, 795, 795,
+ 795, 795, 795, 795, 795, 795, 795, 795,
+
+ 795, 795, 795, 795, 795, 795, 795, 795,
+ 795, 795, 795, 795, 795, 795, 795, 795,
+ 795, 795, 795, 795, 795, 795, 795, 795,
+ 795, 795, 796, 796, 796, 796, 796, 796,
+
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 192, 797, 797, 797, 797, 192, 192,
+ 797, 797, 797, 797, 797, 797, 797, 192,
+ 797, 192, 797, 797, 797, 797, 192, 192,
+
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 192, 797, 797, 797, 797, 192, 192,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 192, 797, 797, 797, 797, 192, 192,
+ 797, 797, 797, 797, 797, 797, 797, 192,
+
+ 797, 192, 797, 797, 797, 797, 192, 192,
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 797, 797, 797, 797, 797, 797, 192,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 192, 797, 797, 797, 797, 192, 192,
+ 797, 797, 797, 797, 797, 797, 797, 798,
+
+ 797, 797, 797, 797, 797, 797, 797, 798,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 797, 797, 797, 797, 797,
+ 797, 797, 797, 192, 192, 799, 799, 800,
+
+ 801, 802, 803, 804, 804, 804, 804, 803,
+ 803, 805, 806, 807, 808, 809, 810, 811,
+ 812, 813, 814, 814, 814, 814, 814, 814,
+ 814, 814, 814, 814, 814, 192, 192, 192,
+
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 815, 815, 815, 815, 815, 815, 815, 815,
+ 815, 815, 192, 192, 192, 192, 192, 192,
+
+ 816, 816, 816, 816, 816, 816, 816, 816,
+ 816, 816, 816, 816, 816, 816, 816, 816,
+ 816, 816, 816, 816, 816, 816, 816, 816,
+ 816, 816, 816, 816, 816, 816, 816, 816,
+
+ 816, 816, 816, 816, 816, 816, 816, 816,
+ 816, 816, 816, 816, 816, 816, 816, 816,
+ 816, 816, 816, 816, 816, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 817, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 818, 818, 818,
+
+ 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 818, 818, 818,
+
+ 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 819, 820, 818,
+ 818, 818, 818, 818, 818, 818, 818, 821,
+ 821, 821, 821, 821, 821, 821, 821, 821,
+
+ 822, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 824, 825, 192, 192, 192,
826, 826, 826, 826, 826, 826, 826, 826,
826, 826, 826, 826, 826, 826, 826, 826,
826, 826, 826, 826, 826, 826, 826, 826,
- 826, 826, 826, 826, 826, 177, 177, 177,
-
- 827, 827, 827, 828, 828, 828, 828, 827,
- 827, 828, 828, 828, 177, 177, 177, 177,
- 828, 828, 827, 828, 828, 828, 828, 828,
- 828, 829, 830, 831, 177, 177, 177, 177,
-
- 832, 177, 177, 177, 833, 833, 834, 835,
- 836, 837, 838, 839, 840, 841, 842, 843,
- 844, 844, 844, 844, 844, 844, 844, 844,
- 844, 844, 844, 844, 844, 844, 844, 844,
-
- 844, 844, 844, 844, 844, 844, 844, 844,
- 844, 844, 844, 844, 844, 844, 177, 177,
- 844, 844, 844, 844, 844, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 845, 845, 845, 845, 845, 845, 845, 845,
- 845, 845, 845, 845, 845, 845, 845, 845,
- 845, 845, 845, 845, 845, 845, 845, 845,
- 845, 845, 845, 845, 845, 845, 845, 845,
-
- 845, 845, 845, 845, 845, 845, 845, 845,
- 845, 845, 846, 846, 177, 177, 177, 177,
- 847, 847, 847, 847, 847, 848, 848, 848,
- 847, 847, 848, 847, 847, 847, 847, 847,
-
- 847, 845, 845, 845, 845, 845, 845, 845,
- 847, 847, 177, 177, 177, 177, 177, 177,
- 849, 850, 851, 852, 853, 854, 855, 856,
- 857, 858, 859, 177, 177, 177, 860, 860,
-
- 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, 861, 861, 861, 861, 861,
-
- 862, 862, 862, 862, 862, 862, 862, 862,
- 862, 862, 862, 862, 862, 862, 862, 862,
- 862, 862, 862, 862, 862, 862, 862, 863,
- 864, 865, 865, 865, 177, 177, 866, 866,
-
- 867, 867, 867, 867, 867, 867, 867, 867,
- 867, 867, 867, 867, 867, 867, 867, 867,
- 867, 867, 867, 867, 867, 867, 867, 867,
- 867, 867, 867, 867, 867, 867, 867, 867,
-
- 867, 867, 867, 867, 867, 867, 867, 867,
- 867, 867, 867, 867, 867, 867, 867, 867,
- 867, 867, 867, 867, 867, 868, 869, 868,
- 869, 869, 869, 869, 869, 869, 869, 177,
-
- 870, 871, 869, 871, 871, 869, 869, 869,
- 869, 869, 869, 869, 869, 868, 868, 868,
- 868, 868, 868, 869, 869, 872, 872, 872,
- 872, 872, 872, 872, 872, 177, 177, 873,
-
- 874, 875, 876, 877, 878, 879, 880, 881,
- 882, 883, 177, 177, 177, 177, 177, 177,
- 874, 875, 876, 877, 878, 879, 880, 881,
- 882, 883, 177, 177, 177, 177, 177, 177,
-
- 884, 884, 884, 884, 884, 884, 884, 885,
- 886, 886, 886, 886, 884, 884, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 887, 887, 887, 887, 888, 889, 889, 889,
- 889, 889, 889, 889, 889, 889, 889, 889,
- 889, 889, 889, 889, 889, 889, 889, 889,
- 889, 889, 889, 889, 889, 889, 889, 889,
-
- 889, 889, 889, 889, 889, 889, 889, 889,
- 889, 889, 889, 889, 889, 889, 889, 889,
- 889, 889, 889, 889, 890, 888, 887, 887,
- 887, 887, 887, 888, 887, 888, 888, 888,
-
- 888, 888, 887, 888, 891, 889, 889, 889,
- 889, 889, 889, 889, 177, 177, 177, 177,
- 892, 893, 894, 895, 896, 897, 898, 899,
- 900, 901, 902, 902, 903, 904, 902, 902,
-
- 904, 905, 905, 905, 905, 905, 905, 905,
- 905, 905, 905, 906, 907, 906, 906, 906,
- 906, 906, 906, 906, 905, 905, 905, 905,
- 905, 905, 905, 905, 905, 177, 177, 177,
-
- 908, 908, 909, 910, 910, 910, 910, 910,
- 910, 910, 910, 910, 910, 910, 910, 910,
- 910, 910, 910, 910, 910, 910, 910, 910,
- 910, 910, 910, 910, 910, 910, 910, 910,
-
- 910, 909, 908, 908, 908, 908, 909, 909,
- 908, 908, 911, 912, 913, 913, 910, 910,
- 914, 915, 916, 917, 918, 919, 920, 921,
- 922, 923, 924, 924, 924, 924, 924, 924,
-
- 925, 925, 925, 925, 925, 925, 925, 925,
- 925, 925, 925, 925, 925, 925, 925, 925,
- 925, 925, 925, 925, 925, 925, 925, 925,
- 925, 925, 925, 925, 925, 925, 925, 925,
-
- 925, 925, 925, 925, 925, 925, 926, 927,
- 928, 928, 927, 927, 927, 928, 927, 928,
- 928, 928, 929, 929, 177, 177, 177, 177,
- 177, 177, 177, 177, 930, 930, 930, 930,
-
- 931, 931, 931, 931, 931, 931, 931, 931,
- 931, 931, 931, 931, 931, 931, 931, 931,
- 931, 931, 931, 931, 931, 931, 931, 931,
- 931, 931, 931, 931, 931, 931, 931, 931,
-
- 931, 931, 931, 931, 932, 932, 932, 932,
- 932, 932, 932, 932, 933, 933, 933, 933,
- 933, 933, 933, 933, 932, 932, 933, 934,
- 177, 177, 177, 935, 935, 936, 936, 936,
-
- 937, 938, 939, 940, 941, 942, 943, 944,
- 945, 946, 177, 177, 177, 931, 931, 931,
- 947, 948, 949, 950, 951, 952, 953, 954,
- 955, 956, 957, 957, 957, 957, 957, 957,
-
- 957, 957, 957, 957, 957, 957, 957, 957,
- 957, 957, 957, 957, 957, 957, 957, 957,
- 957, 957, 957, 957, 957, 957, 957, 957,
- 958, 958, 958, 958, 958, 958, 959, 959,
-
- 960, 960, 960, 960, 960, 960, 960, 960,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 961, 961, 961, 962, 963, 964, 964, 964,
- 964, 964, 961, 961, 964, 964, 964, 964,
-
- 961, 965, 963, 963, 963, 963, 963, 963,
- 963, 966, 966, 966, 966, 964, 966, 966,
- 966, 966, 965, 967, 968, 969, 969, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 105, 105, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 105, 105, 105,
-
- 105, 105, 105, 105, 105, 105, 970, 970,
- 970, 970, 970, 971, 972, 972, 972, 972,
- 972, 972, 972, 972, 972, 972, 972, 972,
- 972, 972, 972, 972, 972, 972, 972, 972,
+ 826, 826, 826, 826, 826, 826, 826, 826,
+ 826, 826, 826, 826, 826, 826, 826, 826,
+ 826, 826, 826, 827, 827, 827, 828, 828,
+ 828, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 829, 829, 829, 829, 829, 829, 829, 829,
+ 829, 829, 829, 829, 829, 192, 829, 829,
+ 829, 829, 830, 830, 831, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 832, 832, 832, 832, 832, 832, 832, 832,
+ 832, 832, 832, 832, 832, 832, 832, 832,
+ 832, 832, 833, 833, 834, 835, 835, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 836, 836, 836, 836, 836, 836, 836, 836,
+ 836, 836, 836, 836, 836, 836, 836, 836,
+ 836, 836, 837, 837, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 838, 838, 838, 838, 838, 838, 838, 838,
+ 838, 838, 838, 838, 838, 192, 838, 838,
+ 838, 192, 839, 839, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 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, 840, 840, 840,
+ 840, 840, 840, 840, 841, 841, 842, 841,
+ 841, 841, 841, 841, 841, 841, 842, 842,
+
+ 842, 842, 842, 842, 842, 842, 841, 842,
+ 842, 841, 841, 841, 841, 841, 841, 841,
+ 841, 841, 843, 841, 844, 844, 845, 846,
+ 844, 847, 844, 848, 840, 849, 192, 192,
+
+ 850, 851, 852, 853, 854, 855, 856, 857,
+ 858, 859, 192, 192, 192, 192, 192, 192,
+ 860, 860, 860, 860, 860, 860, 860, 860,
+ 860, 860, 192, 192, 192, 192, 192, 192,
+
+ 861, 861, 862, 863, 864, 865, 866, 861,
+ 867, 868, 861, 869, 869, 869, 870, 192,
+ 871, 872, 873, 874, 875, 876, 877, 878,
+ 879, 880, 192, 192, 192, 192, 192, 192,
+
+ 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, 881, 881, 881, 881, 881, 881,
+
+ 881, 881, 881, 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, 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, 881,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 881, 881, 881, 881, 881, 881, 881, 881,
+ 881, 883, 884, 192, 192, 192, 192, 192,
+ 821, 821, 821, 821, 821, 821, 821, 821,
+ 821, 821, 821, 821, 821, 821, 821, 821,
+
+ 821, 821, 821, 821, 821, 821, 821, 821,
+ 821, 821, 821, 821, 821, 821, 821, 821,
+ 821, 821, 821, 821, 821, 821, 821, 821,
+ 821, 821, 821, 821, 821, 821, 821, 821,
+
+ 821, 821, 821, 821, 821, 821, 821, 821,
+ 821, 821, 821, 821, 821, 821, 821, 821,
+ 821, 821, 821, 821, 821, 821, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 192, 192, 192,
+
+ 886, 886, 886, 887, 887, 887, 887, 886,
+ 886, 887, 887, 887, 192, 192, 192, 192,
+ 887, 887, 886, 887, 887, 887, 887, 887,
+ 887, 888, 889, 890, 192, 192, 192, 192,
+
+ 891, 192, 192, 192, 892, 892, 893, 894,
+ 895, 896, 897, 898, 899, 900, 901, 902,
+ 903, 903, 903, 903, 903, 903, 903, 903,
+ 903, 903, 903, 903, 903, 903, 903, 903,
+
+ 903, 903, 903, 903, 903, 903, 903, 903,
+ 903, 903, 903, 903, 903, 903, 192, 192,
+ 903, 903, 903, 903, 903, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 904, 904, 904, 904, 904, 904, 904, 904,
+ 904, 904, 904, 904, 904, 904, 904, 904,
+ 904, 904, 904, 904, 904, 904, 904, 904,
+ 904, 904, 904, 904, 904, 904, 904, 904,
+
+ 904, 904, 904, 904, 904, 904, 904, 904,
+ 904, 904, 905, 905, 192, 192, 192, 192,
+ 906, 906, 906, 906, 906, 907, 907, 907,
+ 906, 906, 907, 906, 906, 906, 906, 906,
+
+ 906, 904, 904, 904, 904, 904, 904, 904,
+ 906, 906, 192, 192, 192, 192, 192, 192,
+ 908, 909, 910, 911, 912, 913, 914, 915,
+ 916, 917, 918, 192, 192, 192, 919, 919,
+
+ 920, 920, 920, 920, 920, 920, 920, 920,
+ 920, 920, 920, 920, 920, 920, 920, 920,
+ 920, 920, 920, 920, 920, 920, 920, 920,
+ 920, 920, 920, 920, 920, 920, 920, 920,
+
+ 921, 921, 921, 921, 921, 921, 921, 921,
+ 921, 921, 921, 921, 921, 921, 921, 921,
+ 921, 921, 921, 921, 921, 921, 921, 922,
+ 923, 924, 924, 924, 192, 192, 925, 925,
+
+ 926, 926, 926, 926, 926, 926, 926, 926,
+ 926, 926, 926, 926, 926, 926, 926, 926,
+ 926, 926, 926, 926, 926, 926, 926, 926,
+ 926, 926, 926, 926, 926, 926, 926, 926,
+
+ 926, 926, 926, 926, 926, 926, 926, 926,
+ 926, 926, 926, 926, 926, 926, 926, 926,
+ 926, 926, 926, 926, 926, 927, 928, 927,
+ 928, 928, 928, 928, 928, 928, 928, 192,
+
+ 929, 930, 928, 930, 930, 928, 928, 928,
+ 928, 928, 928, 928, 928, 927, 927, 927,
+ 927, 927, 927, 928, 928, 931, 931, 931,
+ 931, 931, 931, 931, 931, 192, 192, 932,
+
+ 933, 934, 935, 936, 937, 938, 939, 940,
+ 941, 942, 192, 192, 192, 192, 192, 192,
+ 933, 934, 935, 936, 937, 938, 939, 940,
+ 941, 942, 192, 192, 192, 192, 192, 192,
+
+ 943, 943, 943, 943, 943, 943, 943, 944,
+ 945, 945, 945, 945, 943, 943, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 946, 946, 946, 946, 947, 948, 949, 948,
+ 949, 948, 949, 948, 949, 948, 949, 948,
+ 948, 948, 949, 948, 948, 948, 948, 948,
+ 948, 948, 948, 948, 948, 948, 948, 948,
+
+ 948, 948, 948, 948, 948, 948, 948, 948,
+ 948, 948, 948, 948, 948, 948, 948, 948,
+ 948, 948, 948, 948, 950, 951, 946, 946,
+ 946, 946, 946, 952, 946, 952, 947, 947,
+
+ 952, 952, 946, 952, 953, 948, 948, 948,
+ 948, 948, 948, 948, 192, 192, 192, 192,
+ 954, 955, 956, 957, 958, 959, 960, 961,
+ 962, 963, 964, 964, 965, 966, 964, 964,
+
+ 966, 967, 967, 967, 967, 967, 967, 967,
+ 967, 967, 967, 968, 969, 968, 968, 968,
+ 968, 968, 968, 968, 967, 967, 967, 967,
+ 967, 967, 967, 967, 967, 192, 192, 192,
+
+ 970, 970, 971, 972, 972, 972, 972, 972,
972, 972, 972, 972, 972, 972, 972, 972,
972, 972, 972, 972, 972, 972, 972, 972,
972, 972, 972, 972, 972, 972, 972, 972,
- 972, 972, 972, 972, 972, 973, 973, 973,
-
- 973, 973, 972, 972, 972, 972, 973, 973,
- 973, 973, 973, 105, 106, 106, 106, 106,
- 106, 106, 106, 106, 106, 106, 106, 106,
- 974, 975, 106, 106, 106, 976, 106, 106,
-
- 106, 106, 106, 106, 106, 106, 106, 106,
- 106, 106, 106, 106, 106, 106, 106, 106,
- 106, 106, 106, 106, 106, 106, 106, 106,
- 106, 106, 106, 977, 977, 977, 977, 977,
-
- 977, 977, 977, 977, 977, 977, 977, 977,
- 977, 977, 977, 977, 977, 977, 977, 977,
- 977, 977, 977, 977, 977, 977, 977, 977,
- 977, 977, 977, 977, 977, 977, 977, 978,
-
- 167, 167, 166, 167, 979, 979, 979, 979,
- 979, 979, 980, 981, 981, 982, 983, 984,
- 985, 981, 981, 981, 981, 981, 981, 981,
- 981, 981, 981, 981, 981, 981, 981, 981,
-
- 981, 981, 981, 981, 981, 981, 981, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 986, 964, 979, 980,
-
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 987, 988,
- 989, 990, 991, 992, 993, 993, 994, 993,
-
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 67, 68, 67, 68, 67, 68,
- 67, 68, 995, 996, 995, 996, 995, 996,
-
- 997, 997, 997, 997, 997, 997, 997, 997,
- 998, 998, 998, 998, 998, 998, 998, 998,
- 997, 997, 997, 997, 997, 997, 177, 177,
- 998, 998, 998, 998, 998, 998, 177, 177,
-
- 997, 997, 997, 997, 997, 997, 997, 997,
- 998, 998, 998, 998, 998, 998, 998, 998,
- 997, 997, 997, 997, 997, 997, 997, 997,
- 998, 998, 998, 998, 998, 998, 998, 998,
-
- 997, 997, 997, 997, 997, 997, 177, 177,
- 998, 998, 998, 998, 998, 998, 177, 177,
- 999, 997, 1000, 997, 1001, 997, 1002, 997,
- 177, 998, 177, 998, 177, 998, 177, 998,
-
- 997, 997, 997, 997, 997, 997, 997, 997,
- 998, 998, 998, 998, 998, 998, 998, 998,
- 1003, 1003, 1004, 1004, 1004, 1004, 1005, 1005,
- 1006, 1006, 1007, 1007, 1008, 1008, 177, 177,
+ 972, 971, 970, 970, 970, 970, 971, 971,
+ 970, 970, 973, 974, 975, 975, 972, 972,
+ 976, 977, 978, 979, 980, 981, 982, 983,
+ 984, 985, 986, 986, 986, 986, 986, 986,
+
+ 987, 987, 987, 987, 987, 987, 987, 987,
+ 987, 987, 987, 987, 987, 987, 987, 987,
+ 987, 987, 987, 987, 987, 987, 987, 987,
+ 987, 987, 987, 987, 987, 987, 987, 987,
+
+ 987, 987, 987, 987, 987, 987, 988, 989,
+ 990, 990, 989, 989, 989, 990, 989, 990,
+ 990, 990, 991, 991, 192, 192, 192, 192,
+ 192, 192, 192, 192, 992, 992, 992, 992,
+
+ 993, 993, 993, 993, 993, 993, 993, 993,
+ 993, 993, 993, 993, 993, 993, 993, 993,
+ 993, 993, 993, 993, 993, 993, 993, 993,
+ 993, 993, 993, 993, 993, 993, 993, 993,
+
+ 993, 993, 993, 993, 994, 994, 994, 994,
+ 994, 994, 994, 994, 995, 995, 995, 995,
+ 995, 995, 995, 995, 994, 994, 995, 996,
+ 192, 192, 192, 997, 997, 998, 998, 998,
+
+ 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006,
+ 1007, 1008, 192, 192, 192, 993, 993, 993,
1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,
- 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024,
- 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032,
- 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040,
-
- 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048,
- 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056,
- 997, 997, 1057, 1058, 1059, 177, 1060, 1061,
- 998, 998, 1062, 1062, 1063, 176, 1064, 176,
-
- 176, 176, 1065, 1066, 1067, 177, 1068, 1069,
- 1070, 1070, 1070, 1070, 1071, 176, 176, 176,
- 997, 997, 1072, 184, 177, 177, 1073, 1074,
- 998, 998, 1075, 1075, 177, 176, 176, 176,
-
- 997, 997, 1076, 188, 1077, 208, 1078, 1079,
- 998, 998, 1080, 1080, 1081, 176, 176, 176,
- 177, 177, 1082, 1083, 1084, 177, 1085, 1086,
- 1087, 1087, 1088, 1088, 1089, 1090, 176, 177,
-
- 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1092,
- 1091, 1091, 1091, 1093, 1094, 1095, 1096, 1097,
- 1098, 1099, 1098, 1100, 1101, 1102, 14, 14,
- 1103, 1104, 1105, 1106, 1106, 1107, 1105, 1106,
-
- 14, 14, 14, 14, 1108, 1109, 1109, 1110,
- 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118,
- 13, 13, 13, 13, 13, 1119, 1119, 1119,
- 14, 1120, 1121, 14, 1122, 1122, 14, 43,
-
- 43, 14, 14, 14, 1123, 16, 1124, 1125,
- 1126, 1126, 1127, 1127, 1127, 1127, 1128, 1128,
- 1128, 1128, 1129, 1130, 1131, 1132, 1133, 1128,
- 1133, 1133, 1133, 1133, 1132, 1133, 1133, 1134,
-
- 1135, 1136, 1136, 1136, 1137, 1138, 1138, 1138,
- 1138, 1138, 1139, 1139, 1139, 1139, 1139, 1139,
- 1140, 1141, 177, 177, 1142, 1143, 1144, 1145,
- 1146, 1147, 1148, 1148, 36, 16, 1124, 142,
-
- 1140, 62, 57, 58, 1142, 1143, 1144, 1145,
- 1146, 1147, 1148, 1148, 36, 16, 1124, 177,
- 977, 977, 977, 977, 977, 1149, 1149, 1149,
- 1149, 1149, 1149, 1149, 1149, 177, 177, 177,
+ 1017, 1018, 1019, 1019, 1019, 1019, 1019, 1019,
+
+ 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019,
+ 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019,
+ 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019,
+ 1020, 1020, 1020, 1020, 1020, 1020, 1021, 1021,
+
+ 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1023, 1023, 1023, 1024, 1025, 1026, 1026, 1026,
+ 1026, 1026, 1023, 1023, 1026, 1026, 1026, 1026,
+
+ 1023, 1027, 1025, 1025, 1025, 1025, 1025, 1025,
+ 1025, 1028, 1028, 1028, 1028, 1026, 1028, 1028,
+ 1028, 1028, 1027, 1029, 1030, 1031, 1031, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 114, 114, 114, 114, 114, 114, 114, 114,
+ 114, 114, 114, 114, 114, 114, 114, 114,
+ 114, 114, 114, 114, 114, 114, 114, 114,
+ 114, 114, 114, 114, 114, 114, 114, 114,
+
+ 114, 114, 114, 114, 114, 114, 1032, 1032,
+ 1032, 1032, 1032, 1033, 1034, 1034, 1034, 1035,
+ 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
+ 1034, 1034, 1034, 1035, 1034, 1034, 1034, 1034,
+
+ 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
+ 1034, 1034, 1034, 1034, 1034, 1034, 1035, 1034,
+ 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
+ 1034, 1034, 1034, 1034, 1034, 1036, 1036, 1036,
+
+ 1036, 1036, 1034, 1034, 1034, 1034, 1036, 1036,
+ 1036, 1036, 1036, 114, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115,
+ 1037, 1038, 115, 115, 115, 1039, 115, 115,
+
+ 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 1040, 1040, 1040, 1040, 1040,
+
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1041,
+
+ 181, 181, 180, 181, 1042, 1042, 1042, 1042,
+ 1042, 1042, 1043, 1044, 1044, 1045, 1046, 1047,
+ 1048, 1044, 1044, 1044, 1044, 1044, 1044, 1044,
+ 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044,
+
+ 1044, 1044, 1044, 1044, 1044, 1044, 1044, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 1049, 1026, 1042, 1043,
+
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 1050, 1051,
+ 1052, 1053, 1054, 1055, 1056, 1056, 1057, 1056,
+
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 70, 71, 70, 71, 70, 71,
+ 70, 71, 1058, 1059, 1058, 1059, 1058, 1059,
+
+ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
+ 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
+ 1060, 1060, 1060, 1060, 1060, 1060, 192, 192,
+ 1061, 1061, 1061, 1061, 1061, 1061, 192, 192,
+
+ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
+ 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
+ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
+ 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
+
+ 1060, 1060, 1060, 1060, 1060, 1060, 192, 192,
+ 1061, 1061, 1061, 1061, 1061, 1061, 192, 192,
+ 1062, 1060, 1063, 1060, 1064, 1060, 1065, 1060,
+ 192, 1061, 192, 1061, 192, 1061, 192, 1061,
+
+ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
+ 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
+ 1066, 1067, 1068, 1069, 1068, 1069, 1070, 1071,
+ 1072, 1073, 1074, 1075, 1076, 1077, 192, 192,
+
+ 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085,
+ 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093,
+ 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101,
+ 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109,
+
+ 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117,
+ 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125,
+ 1060, 1060, 1126, 1127, 1128, 192, 1129, 1130,
+ 1061, 1061, 1131, 1132, 1133, 196, 1134, 196,
+
+ 196, 1135, 1136, 1137, 1138, 192, 1139, 1140,
+ 1141, 1142, 1141, 1142, 1143, 1135, 1135, 1135,
+ 1060, 1060, 1144, 1145, 192, 192, 1146, 1147,
+ 1061, 1061, 1148, 1149, 192, 1135, 1135, 1135,
+
+ 1060, 1060, 1150, 1151, 1152, 1153, 1154, 1155,
+ 1061, 1061, 1156, 1157, 1158, 1135, 1159, 1159,
+ 192, 192, 1160, 1161, 1162, 192, 1163, 1164,
+ 1165, 1166, 1167, 1168, 1169, 1170, 196, 192,
+
+ 1171, 1171, 1172, 1172, 1172, 1172, 1172, 1173,
+ 1172, 1172, 1172, 1174, 1175, 1176, 1177, 1178,
+ 1179, 1180, 1179, 1181, 1182, 1183, 14, 1184,
+ 1185, 1186, 1187, 1188, 1188, 1189, 1187, 1188,
+
+ 14, 14, 14, 14, 1190, 1191, 1191, 1192,
+ 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200,
+ 13, 13, 13, 1201, 1201, 1202, 1203, 1203,
+ 14, 1204, 1205, 14, 1206, 1207, 1184, 43,
+
+ 43, 14, 14, 14, 1208, 16, 1209, 1210,
+ 1211, 1211, 1212, 1212, 1212, 1212, 1213, 1213,
+ 1213, 1213, 1214, 1215, 1216, 1217, 1218, 1219,
+ 1218, 1218, 1218, 1218, 1217, 1218, 1218, 1220,
+
+ 1221, 1222, 1222, 1222, 1223, 1224, 1224, 1224,
+ 1224, 1224, 1225, 1225, 1225, 1225, 1225, 1225,
+ 1226, 1227, 192, 192, 1228, 1229, 1230, 1231,
+ 1232, 1233, 1234, 1234, 1235, 1236, 1237, 151,
+
+ 1226, 63, 58, 59, 1228, 1229, 1230, 1231,
+ 1232, 1233, 1234, 1234, 1235, 1236, 1237, 192,
+ 1040, 1040, 1040, 1040, 1040, 1238, 1238, 1238,
+ 1238, 1238, 1238, 1238, 1238, 192, 192, 192,
12, 12, 12, 12, 12, 12, 12, 50,
- 12, 12, 12, 1150, 1151, 1152, 1152, 1152,
- 1153, 1153, 1154, 1154, 1154, 1154, 1155, 1156,
- 1156, 1157, 1158, 177, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 153, 153, 158, 158, 153, 153, 153, 153,
- 158, 158, 158, 153, 153, 1159, 1159, 1159,
-
- 1159, 153, 1160, 1160, 1161, 1162, 1162, 173,
- 1163, 173, 1162, 1164, 980, 980, 980, 980,
- 981, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 51, 51, 1165, 1166, 51, 51, 51, 1165,
- 51, 1166, 1167, 1165, 1165, 1165, 1167, 1167,
- 1165, 1165, 1165, 1167, 51, 1165, 1168, 51,
- 36, 1165, 1165, 1165, 1165, 1165, 51, 51,
-
- 51, 51, 51, 51, 1165, 51, 1169, 51,
- 1165, 51, 1170, 1171, 1165, 1165, 1172, 1167,
- 1165, 1165, 1173, 1165, 1167, 1174, 1174, 1174,
- 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1180,
-
- 1129, 1129, 1129, 1129, 1129, 1180, 1179, 1179,
- 1179, 1179, 1181, 1129, 1182, 1183, 1184, 1185,
- 1186, 1186, 1186, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
-
- 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187,
- 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187,
- 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188,
- 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188,
-
- 1189, 1189, 1189, 102, 113, 1190, 1190, 1190,
- 1190, 1186, 177, 177, 177, 177, 177, 177,
+ 1239, 12, 12, 1240, 1241, 1242, 1242, 1242,
+ 1243, 1243, 1244, 1244, 1244, 1244, 1245, 1246,
+ 1246, 1247, 1248, 192, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 163, 163, 170, 170, 163, 163, 163, 163,
+ 170, 170, 170, 163, 163, 1249, 1249, 1249,
+
+ 1249, 163, 1250, 1250, 1251, 1252, 1252, 187,
+ 1253, 187, 1252, 1254, 1043, 1043, 1043, 1043,
+ 1044, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1255, 1255, 1256, 1257, 51, 1255, 1255, 1256,
+ 51, 1257, 1258, 1256, 1256, 1256, 1258, 1258,
+ 1256, 1256, 1256, 1258, 51, 1256, 1259, 51,
+ 36, 1256, 1256, 1256, 1256, 1256, 51, 51,
+
+ 1255, 1255, 1255, 51, 1256, 51, 1260, 51,
+ 1256, 51, 1261, 1262, 1256, 1256, 1263, 1258,
+ 1256, 1256, 1264, 1256, 1258, 1265, 1265, 1265,
+ 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1271,
+
+ 1272, 1214, 1214, 1214, 1214, 1271, 1270, 1270,
+ 1270, 1270, 1273, 1214, 1274, 1275, 1276, 1277,
+ 1278, 1278, 1278, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65,
+
+ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279,
+ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279,
+ 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280,
+ 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280,
+
+ 1281, 1281, 1281, 111, 122, 1282, 1282, 1282,
+ 1282, 1278, 192, 192, 192, 192, 192, 192,
36, 36, 36, 36, 36, 51, 51, 51,
- 51, 51, 36, 36, 51, 51, 51, 51,
+ 51, 51, 1283, 1283, 51, 51, 51, 51,
36, 51, 51, 36, 51, 51, 36, 51,
- 51, 51, 51, 51, 51, 51, 36, 51,
+ 51, 51, 51, 51, 51, 51, 1283, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 36, 36,
+ 51, 51, 51, 51, 51, 1284, 1283, 1283,
51, 51, 36, 51, 36, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 1176, 1176, 1176, 1176, 1176,
- 1176, 1176, 1176, 1176, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ 51, 51, 51, 1267, 1267, 1267, 1267, 1267,
+ 1267, 1267, 1267, 1267, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 36, 36, 36, 36, 36, 36, 36, 36,
- 1191, 1191, 1191, 1192, 1192, 1192, 36, 36,
- 36, 36, 18, 56, 36, 1193, 36, 36,
+ 36, 36, 36, 36, 1283, 36, 36, 36,
+ 1285, 1286, 1285, 1287, 1288, 1287, 36, 36,
+ 36, 36, 18, 57, 36, 1289, 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, 1194, 1195, 36, 36,
+ 36, 36, 36, 36, 1283, 36, 1283, 36,
+ 36, 36, 36, 36, 1235, 1235, 36, 1235,
+ 1235, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 1290, 1291, 36, 36,
- 36, 36, 36, 1196, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 1194, 1195, 1194, 1195, 36, 36,
+ 36, 1283, 36, 1292, 1283, 36, 36, 1283,
+ 36, 1283, 36, 36, 36, 36, 36, 36,
+ 36, 36, 1290, 1291, 1290, 1291, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 1194, 1195, 1194, 1195,
- 1194, 1195, 1194, 1195, 36, 36, 1194, 1195,
- 1194, 1195, 1194, 1195, 1194, 1195, 1194, 1195,
- 1194, 1195, 1194, 1195, 1194, 1195, 1194, 1195,
+ 1283, 36, 1283, 36, 1290, 1291, 1290, 1291,
+ 1290, 1291, 1290, 1291, 36, 1283, 1293, 1294,
+ 1293, 1294, 1290, 1291, 1293, 1294, 1290, 1291,
+ 1293, 1294, 1290, 1291, 1290, 1291, 1290, 1291,
- 1194, 1195, 1194, 1195, 1194, 1195, 1194, 1195,
- 1194, 1195, 1194, 1195, 36, 36, 36, 1194,
- 1195, 1194, 1195, 36, 36, 36, 36, 36,
- 1197, 36, 36, 36, 36, 36, 36, 36,
+ 1293, 1294, 1290, 1291, 1293, 1294, 1290, 1291,
+ 1293, 1294, 1290, 1291, 36, 36, 36, 1290,
+ 1291, 1290, 1291, 36, 36, 36, 36, 36,
+ 1295, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 1194, 1195, 36, 36, 1198, 36,
- 1199, 1200, 36, 1200, 36, 36, 36, 36,
- 1194, 1195, 1194, 1195, 1194, 1195, 1194, 1195,
+ 36, 36, 1290, 1291, 36, 36, 1296, 36,
+ 1297, 1298, 36, 1298, 1283, 1283, 1283, 1283,
+ 1290, 1291, 1290, 1291, 1290, 1291, 1290, 1291,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
- 36, 1194, 1195, 1194, 1195, 1201, 36, 36,
- 1194, 1195, 36, 36, 36, 36, 1194, 1195,
- 1194, 1195, 1194, 1195, 1194, 1195, 1194, 1195,
+ 36, 1290, 1291, 1290, 1291, 1299, 36, 36,
+ 1290, 1291, 36, 36, 36, 36, 1290, 1291,
+ 1290, 1291, 1290, 1291, 1290, 1291, 1290, 1291,
- 1194, 1195, 1194, 1195, 1194, 1195, 1194, 1195,
- 1194, 1195, 1194, 1195, 1194, 1195, 36, 36,
- 1194, 1195, 1202, 1202, 1202, 1129, 1203, 1203,
- 1129, 1129, 1204, 1204, 1204, 1205, 1205, 1129,
+ 1293, 1294, 1293, 1294, 1290, 1291, 1290, 1291,
+ 1290, 1291, 1293, 1294, 1293, 1294, 36, 36,
+ 1290, 1291, 1300, 1300, 1300, 1214, 1301, 1301,
+ 1214, 1214, 1302, 1302, 1302, 1303, 1303, 1214,
- 51, 1176, 51, 51, 51, 51, 51, 51,
- 1194, 1195, 1194, 1195, 51, 51, 51, 51,
+ 51, 1267, 51, 51, 51, 51, 51, 51,
+ 1290, 1291, 1290, 1291, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 1206, 1206, 51, 51, 51, 51,
+ 51, 51, 1304, 1304, 51, 51, 51, 51,
36, 36, 51, 51, 51, 51, 51, 51,
- 51, 16, 1124, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
-
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
-
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1176, 1129, 1176, 1176, 1176,
-
- 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176,
- 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176,
- 1176, 1176, 1176, 1176, 1176, 1208, 1176, 1176,
- 1176, 1176, 1176, 1129, 1129, 1129, 1129, 1129,
-
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1181, 1181, 1181, 1181,
- 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
-
- 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
- 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1177,
- 1177, 1182, 1182, 1182, 1182, 1182, 1182, 1182,
- 1182, 1182, 1182, 1182, 1209, 1209, 1209, 1209,
-
- 1209, 1209, 1183, 1183, 1183, 1183, 1183, 1183,
- 1210, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1212, 1212, 1212, 1212, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
+ 51, 1305, 1306, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 1307, 1307,
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1307, 1307, 1267, 1214, 1267, 1267, 1267,
+
+ 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
+ 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
+ 1267, 1267, 1267, 1267, 1267, 1308, 1267, 1267,
+ 1267, 1267, 1267, 1214, 1214, 1214, 1214, 1214,
+
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1273, 1273, 1273, 1273,
+ 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
+
+ 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
+ 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1309,
+ 1309, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ 1274, 1274, 1274, 1274, 1310, 1310, 1310, 1310,
+
+ 1310, 1310, 1275, 1275, 1275, 1275, 1275, 1275,
+ 1311, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1313, 1313, 1313, 1313, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 1176, 1176, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
+ 51, 51, 51, 51, 51, 1267, 1267, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220,
- 1221, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 1213, 1214, 1215, 1216,
- 1217, 1218, 1219, 1220, 1221, 64, 64, 64,
-
- 64, 64, 64, 64, 64, 64, 64, 64,
- 62, 57, 58, 1142, 1143, 1144, 1145, 1146,
- 1147, 1222, 1222, 1222, 1222, 1222, 1222, 1222,
- 1222, 1222, 1222, 1222, 1207, 1207, 1207, 1207,
-
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1207, 1207, 1207, 1223, 1223,
- 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223,
-
- 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223,
- 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
-
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1225, 1226, 1226, 1226, 1226, 1226,
- 1226, 1226, 1226, 1226, 1226, 1227, 1228, 1229,
- 1230, 1231, 1232, 1233, 1234, 1235, 1226, 1236,
+ 51, 51, 51, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321,
+ 1322, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 1314, 1315, 1316, 1317,
+ 1318, 1319, 1320, 1321, 1322, 65, 65, 65,
+
+ 65, 65, 65, 65, 65, 65, 65, 65,
+ 63, 58, 59, 1228, 1229, 1230, 1231, 1232,
+ 1233, 1323, 1323, 1323, 1323, 1323, 1323, 1323,
+ 1323, 1323, 1323, 1323, 1324, 1324, 1324, 1324,
+
+ 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324,
+ 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324,
+ 1324, 1324, 1324, 1324, 1324, 1324, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1327, 1328, 1328, 1328, 1328, 1328,
+ 1328, 1328, 1328, 1328, 1328, 1329, 1330, 1331,
+ 1332, 1333, 1334, 1335, 1336, 1337, 1328, 1338,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 1181, 1181,
- 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
+ 51, 51, 51, 51, 51, 51, 1273, 1273,
+ 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
@@ -2176,2654 +2191,2707 @@ static const unsigned short uc_property_trie[] = {
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1206, 1206, 1206, 1206, 51, 51, 51, 51,
+ 1304, 1304, 1304, 1304, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 1237, 1237, 1181, 1181,
- 1238, 1176, 1206, 1206, 1206, 1206, 1206, 1206,
+ 51, 51, 51, 51, 1339, 1339, 1273, 1273,
+ 1340, 1267, 1304, 1304, 1304, 1304, 1304, 1304,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 1206, 1206, 1206, 51, 51, 51, 51,
+ 51, 1304, 1304, 1304, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1206, 51, 51, 51, 51, 51, 51, 36,
- 1176, 1176, 1181, 1181, 1181, 1181, 1181, 1181,
- 1181, 1181, 1181, 1181, 1181, 1181, 1182, 1238,
-
- 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
- 1181, 1181, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1182, 1182, 1182, 1182, 1182, 1182,
- 1182, 1182, 1182, 1182, 1182, 1239, 1210, 1210,
-
- 1177, 1177, 1182, 1182, 1182, 1182, 1182, 1182,
- 1182, 1182, 1182, 1182, 1240, 1182, 1182, 1182,
- 1182, 1182, 1183, 1239, 1239, 1239, 1239, 1239,
- 1239, 1239, 1239, 1239, 1239, 1241, 1241, 1241,
-
- 1242, 1242, 1242, 1242, 1241, 1241, 1241, 1241,
- 1241, 1210, 1210, 1210, 1210, 1241, 1211, 1241,
- 1241, 1241, 1210, 1241, 1241, 1210, 1210, 1210,
- 1241, 1241, 1210, 1210, 1241, 1210, 1210, 1241,
-
- 1241, 1241, 1211, 1210, 1211, 1211, 1211, 1211,
- 1210, 1210, 1241, 1210, 1210, 1210, 1210, 1210,
- 1210, 1241, 1241, 1241, 1241, 1241, 1210, 1241,
- 1241, 1241, 1241, 1210, 1210, 1241, 1241, 1241,
-
- 177, 1206, 1206, 1206, 1206, 1211, 51, 51,
- 1206, 1206, 1212, 1212, 1206, 1206, 51, 51,
+ 1304, 51, 51, 51, 51, 51, 51, 36,
+ 1267, 1267, 1273, 1273, 1273, 1273, 1273, 1273,
+ 1273, 1273, 1273, 1273, 1273, 1273, 1274, 1340,
+
+ 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
+ 1273, 1273, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1274, 1274, 1274, 1274, 1274, 1274,
+ 1274, 1274, 1274, 1274, 1274, 1341, 1311, 1311,
+
+ 1309, 1309, 1274, 1274, 1274, 1274, 1274, 1274,
+ 1274, 1274, 1274, 1274, 1342, 1274, 1274, 1274,
+ 1274, 1274, 1275, 1341, 1341, 1341, 1341, 1341,
+ 1341, 1341, 1341, 1341, 1341, 1343, 1343, 1343,
+
+ 1344, 1344, 1344, 1344, 1343, 1343, 1343, 1343,
+ 1343, 1311, 1311, 1311, 1311, 1343, 1312, 1343,
+ 1343, 1343, 1311, 1343, 1343, 1311, 1311, 1311,
+ 1343, 1343, 1311, 1311, 1343, 1311, 1311, 1343,
+
+ 1343, 1343, 1312, 1311, 1312, 1312, 1312, 1312,
+ 1311, 1311, 1343, 1311, 1311, 1311, 1311, 1311,
+ 1311, 1343, 1343, 1343, 1343, 1343, 1311, 1343,
+ 1343, 1343, 1343, 1311, 1311, 1343, 1343, 1343,
+
+ 192, 1304, 1304, 1304, 1304, 1312, 51, 51,
+ 1304, 1304, 1313, 1313, 1304, 1304, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1211, 51, 51, 51, 51, 51, 51, 51,
+ 1312, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 1211, 51, 1211, 51,
- 51, 51, 51, 1211, 1211, 1211, 51, 1210,
- 51, 51, 51, 1243, 1243, 1243, 1243, 1211,
-
- 1211, 51, 1244, 1244, 51, 51, 51, 51,
- 1245, 1246, 1245, 1246, 1245, 1246, 1245, 1246,
- 1245, 1246, 1245, 1246, 1245, 1246, 1213, 1214,
- 1215, 1216, 1217, 1218, 1219, 1220, 1221, 64,
-
- 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220,
- 1221, 64, 1213, 1214, 1215, 1216, 1217, 1218,
- 1219, 1220, 1221, 64, 51, 1211, 1211, 1211,
+ 51, 51, 51, 51, 1312, 51, 1312, 51,
+ 51, 51, 51, 1312, 1312, 1312, 51, 1311,
+ 51, 51, 51, 1345, 1345, 1345, 1345, 1312,
+
+ 1312, 51, 1346, 1346, 51, 51, 51, 51,
+ 1347, 1348, 1347, 1348, 1347, 1348, 1347, 1348,
+ 1347, 1348, 1347, 1348, 1347, 1348, 1349, 1350,
+ 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358,
+
+ 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356,
+ 1357, 1358, 1349, 1350, 1351, 1352, 1353, 1354,
+ 1355, 1356, 1357, 1358, 51, 1312, 1312, 1312,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1211, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 1211,
-
- 1247, 1247, 1247, 1248, 1249, 1250, 1251, 1209,
- 1252, 1253, 1209, 1254, 1255, 1256, 1257, 1257,
- 1129, 1129, 1129, 1129, 1129, 1258, 1259, 1129,
- 1129, 1129, 1129, 1129, 1129, 1258, 1259, 1129,
-
- 1129, 1129, 1258, 1259, 1258, 1259, 1245, 1246,
- 1245, 1246, 1245, 1246, 1260, 1261, 1260, 1261,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
-
- 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262,
- 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262,
- 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262,
- 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262,
-
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
-
- 1129, 1129, 1129, 1245, 1246, 1245, 1246, 1245,
- 1246, 1245, 1246, 1245, 1246, 1263, 1264, 1265,
- 1266, 1245, 1246, 1245, 1246, 1245, 1246, 1245,
- 1246, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
-
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1267, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
-
- 1258, 1259, 1129, 1129, 1258, 1259, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1258,
- 1259, 1258, 1259, 1129, 1258, 1259, 1129, 1129,
- 1245, 1246, 1245, 1246, 1129, 1129, 1129, 1129,
-
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1268, 1129, 1129,
- 1258, 1259, 1129, 1129, 1245, 1246, 1129, 1129,
-
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1258, 1259, 1258, 1259, 1129,
- 1129, 1129, 1129, 1129, 1258, 1259, 1129, 1129,
- 1129, 1129, 1129, 1129, 1258, 1259, 1129, 1129,
-
- 1129, 1129, 1129, 1129, 1258, 1259, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1258, 1259, 1129, 1129, 1258, 1259, 1258,
-
- 1259, 1258, 1259, 1258, 1259, 1129, 1129, 1129,
- 1129, 1129, 1129, 1258, 1259, 1129, 1129, 1129,
- 1129, 1258, 1259, 1258, 1259, 1258, 1259, 1258,
- 1259, 1258, 1259, 1258, 1259, 1129, 1129, 1129,
-
- 1129, 1258, 1259, 1129, 1129, 1129, 1258, 1259,
- 1258, 1259, 1258, 1259, 1258, 1259, 1129, 1258,
- 1259, 1129, 1129, 1258, 1259, 1129, 1129, 1129,
- 1129, 1129, 1129, 1258, 1259, 1258, 1259, 1258,
-
- 1259, 1258, 1259, 1258, 1259, 1258, 1259, 1129,
- 1129, 1129, 1129, 1129, 1129, 1258, 1259, 1258,
- 1259, 1258, 1259, 1258, 1259, 1258, 1259, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1269, 1129,
-
- 1129, 1129, 1129, 1270, 1271, 1270, 1129, 1129,
- 1129, 1129, 1129, 1129, 1258, 1259, 1129, 1129,
- 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1258,
- 1259, 1258, 1259, 1129, 1129, 1129, 1129, 1129,
-
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1182, 1182,
- 1182, 1182, 1182, 1182, 1183, 1183, 1183, 1183,
- 1183, 1183, 1183, 1239, 1239, 1239, 1239, 1239,
-
- 1183, 1183, 1183, 1183, 1239, 1239, 1239, 1239,
- 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239,
- 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255,
- 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255,
-
- 1255, 1255, 1255, 1255, 1255, 1239, 1239, 1255,
- 1255, 1255, 1255, 1255, 1255, 177, 177, 177,
- 1239, 1239, 1239, 1239, 1239, 1210, 1210, 1210,
- 1210, 1210, 177, 177, 177, 177, 177, 177,
-
- 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272,
- 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272,
- 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272,
- 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272,
-
- 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272,
- 1272, 1272, 1272, 1272, 1272, 1272, 1272, 177,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
+ 1312, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 1312,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 177,
-
- 117, 113, 1274, 1275, 1276, 1277, 1278, 117,
- 113, 117, 113, 117, 113, 1279, 1280, 1281,
- 1282, 993, 995, 996, 1283, 117, 113, 1283,
- 993, 993, 993, 993, 1284, 1284, 1285, 1285,
-
- 1286, 1287, 1286, 1287, 1286, 1287, 1286, 1287,
- 1286, 1287, 1286, 1287, 1286, 1287, 1286, 1287,
- 1286, 1287, 1286, 1287, 1286, 1287, 1286, 1287,
- 1286, 1287, 1286, 1287, 1286, 1287, 1286, 1287,
-
- 1286, 1287, 1286, 1287, 1288, 1289, 1289, 1289,
- 1289, 1289, 1289, 1290, 1291, 1290, 1291, 1292,
- 1292, 1292, 1293, 1294, 177, 177, 177, 177,
- 177, 1295, 1296, 1296, 1296, 1297, 1295, 1296,
-
- 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298,
- 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298,
- 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298,
- 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298,
-
- 1298, 1298, 1298, 1298, 1298, 1298, 177, 1299,
- 177, 177, 177, 177, 177, 1299, 177, 177,
- 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300,
- 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300,
-
- 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300,
- 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300,
- 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300,
- 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300,
-
- 1300, 1300, 1300, 1300, 1300, 1300, 1301, 1301,
- 177, 177, 177, 177, 177, 177, 177, 1302,
- 1303, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 1304,
-
- 739, 739, 739, 739, 739, 739, 739, 739,
- 739, 739, 739, 739, 739, 739, 739, 739,
- 739, 739, 739, 739, 739, 739, 739, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 739, 739, 739, 739, 739, 739, 739, 177,
- 739, 739, 739, 739, 739, 739, 739, 177,
- 739, 739, 739, 739, 739, 739, 739, 177,
- 739, 739, 739, 739, 739, 739, 739, 177,
-
- 228, 228, 228, 228, 228, 228, 228, 228,
- 228, 228, 228, 228, 228, 228, 228, 228,
- 228, 228, 228, 228, 228, 228, 228, 228,
- 228, 228, 228, 228, 228, 228, 228, 228,
-
- 1305, 1305, 1306, 1307, 1306, 1307, 1305, 1305,
- 1305, 1306, 1307, 1305, 1306, 1307, 1133, 1133,
- 1133, 1133, 1133, 1133, 1133, 1133, 1132, 1308,
- 1309, 1310, 1311, 1312, 1306, 1307, 1312, 1312,
-
- 1313, 1314, 1260, 1261, 1260, 1261, 1260, 1261,
- 1260, 1261, 1310, 1310, 1310, 1310, 1315, 1316,
- 1310, 1317, 1318, 1319, 1319, 1318, 1318, 1318,
- 1318, 1318, 1320, 1320, 177, 177, 177, 177,
-
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 177, 1321, 1321, 1321, 1321, 1321,
-
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
-
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321,
- 1321, 1321, 1321, 1321, 1321, 1321, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- 1322, 1322, 1322, 1322, 177, 177, 177, 177,
-
- 1323, 1324, 1325, 1326, 1206, 1327, 1328, 1329,
- 16, 1124, 16, 1124, 16, 1124, 16, 1124,
- 16, 1124, 1206, 1206, 16, 1124, 16, 1124,
- 16, 1124, 16, 1124, 1330, 1105, 1331, 1331,
-
- 1206, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
- 1329, 1329, 1332, 1333, 154, 1334, 1335, 1335,
- 1336, 1337, 1337, 1337, 1337, 1337, 1206, 1206,
- 1338, 1338, 1338, 1339, 1340, 1341, 1322, 1206,
-
- 177, 1342, 1343, 1342, 1343, 1342, 1343, 1342,
- 1343, 1342, 1343, 1343, 1343, 1343, 1343, 1343,
- 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
- 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
-
- 1343, 1343, 1343, 1342, 1343, 1343, 1343, 1343,
- 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
- 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
- 1343, 1343, 1343, 1343, 1343, 1343, 1343, 1343,
-
- 1343, 1343, 1343, 1342, 1343, 1342, 1343, 1342,
- 1343, 1343, 1343, 1343, 1343, 1343, 1342, 1343,
- 1343, 1343, 1343, 1343, 1343, 1344, 1344, 177,
- 177, 1345, 1345, 1346, 1346, 1347, 1347, 1348,
-
- 1349, 1350, 1351, 1350, 1351, 1350, 1351, 1350,
- 1351, 1350, 1351, 1351, 1351, 1351, 1351, 1351,
- 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
- 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
-
- 1351, 1351, 1351, 1350, 1351, 1351, 1351, 1351,
- 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
- 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
- 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
-
- 1351, 1351, 1351, 1350, 1351, 1350, 1351, 1350,
- 1351, 1351, 1351, 1351, 1351, 1351, 1350, 1351,
- 1351, 1351, 1351, 1351, 1351, 1350, 1350, 1351,
- 1351, 1351, 1351, 1352, 1353, 1354, 1354, 1355,
-
- 177, 177, 177, 177, 177, 1356, 1356, 1356,
- 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
-
- 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- 1356, 1356, 1356, 1356, 1356, 1357, 177, 177,
- 177, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
-
- 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
-
- 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- 1358, 1358, 1358, 1358, 1358, 1358, 1358, 177,
- 1359, 1359, 1360, 1360, 1360, 1360, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
-
- 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361,
- 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361,
- 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361,
- 1362, 1362, 1362, 177, 177, 177, 177, 177,
-
- 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
- 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
-
- 1242, 1242, 1242, 1242, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363,
- 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363,
-
- 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364,
- 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364,
- 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364,
- 1364, 1364, 1364, 1364, 1364, 1365, 1365, 177,
-
- 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360,
- 1360, 1360, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
-
- 1359, 1359, 1359, 1359, 1366, 1366, 1366, 1366,
- 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367,
- 1237, 1368, 1368, 1368, 1368, 1368, 1368, 1368,
- 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368,
-
- 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364,
- 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364,
- 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364,
- 1364, 1364, 1364, 1364, 1365, 1365, 1369, 1359,
-
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1368, 1368, 1368, 1368, 1368, 1368, 1368,
- 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368,
-
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1237, 1237, 1237, 1237,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
-
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 177,
-
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
-
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
-
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1237,
- 1237, 1237, 1237, 1359, 1359, 1359, 1359, 1359,
-
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
-
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1237, 1237,
-
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
- 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1237,
-
- 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371,
- 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371,
- 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371,
- 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371,
-
- 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371,
- 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371,
- 1371, 1371, 1371, 1371, 1371, 1371, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
-
- 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373,
- 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373,
- 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373,
- 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373,
-
- 1373, 1373, 1373, 1373, 1373, 1373, 1374, 1374,
+ 1359, 1359, 1359, 1360, 1361, 1362, 1363, 1310,
+ 1364, 1365, 1310, 1366, 1367, 1368, 1369, 1369,
+ 1214, 1214, 1214, 1214, 1214, 1370, 1371, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1370, 1371, 1214,
+
+ 1214, 1214, 1370, 1371, 1370, 1371, 1347, 1348,
+ 1347, 1348, 1347, 1348, 1372, 1373, 1372, 1373,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+
+ 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
+ 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1375, 1375, 1375, 1375,
-
- 1375, 1375, 1375, 1375, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1377, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 1379, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
-
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
-
- 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 177, 177, 177,
- 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380,
- 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380,
-
- 1380, 1380, 1381, 1381, 1380, 1380, 1380, 1380,
- 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380,
- 1380, 1380, 1380, 1380, 1381, 1380, 1380, 1380,
- 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380,
-
- 1380, 1381, 1380, 1380, 1380, 1381, 1380, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382,
- 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382,
-
- 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382,
- 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382,
- 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382,
- 1383, 1383, 1383, 1383, 1383, 1383, 1384, 1385,
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+
+ 1214, 1214, 1214, 1347, 1348, 1347, 1348, 1347,
+ 1348, 1347, 1348, 1347, 1348, 1375, 1376, 1377,
+ 1378, 1347, 1348, 1347, 1348, 1347, 1348, 1347,
+ 1348, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1379, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+
+ 1370, 1371, 1214, 1214, 1370, 1371, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1370,
+ 1371, 1370, 1371, 1214, 1370, 1371, 1214, 1214,
+ 1347, 1348, 1347, 1348, 1214, 1214, 1214, 1214,
+
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1380, 1214, 1214,
+ 1370, 1371, 1214, 1214, 1347, 1348, 1214, 1214,
+
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1272, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1370, 1371, 1370, 1371, 1214,
+ 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
+
+ 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1272, 1272, 1272, 1214,
+ 1214, 1370, 1371, 1214, 1214, 1370, 1371, 1370,
+
+ 1371, 1370, 1371, 1370, 1371, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1370, 1371, 1214, 1214, 1214,
+ 1214, 1370, 1371, 1370, 1371, 1370, 1371, 1370,
+ 1371, 1370, 1371, 1370, 1371, 1214, 1214, 1214,
+
+ 1214, 1370, 1371, 1214, 1214, 1214, 1370, 1371,
+ 1370, 1371, 1370, 1371, 1370, 1371, 1214, 1370,
+ 1371, 1214, 1214, 1370, 1371, 1214, 1214, 1214,
+ 1214, 1214, 1214, 1370, 1371, 1370, 1371, 1370,
+
+ 1371, 1370, 1371, 1370, 1371, 1370, 1371, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1370, 1371, 1370,
+ 1371, 1370, 1371, 1370, 1371, 1370, 1371, 1214,
+ 1214, 1214, 1214, 1214, 1381, 1214, 1382, 1214,
+
+ 1214, 1214, 1214, 1383, 1384, 1383, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1370,
+ 1371, 1370, 1371, 1214, 1214, 1214, 1214, 1214,
+
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1274, 1274,
+ 1274, 1274, 1274, 1274, 1275, 1275, 1275, 1275,
+ 1275, 1275, 1275, 1341, 1341, 1341, 1341, 1341,
+
+ 1275, 1275, 1275, 1275, 1341, 1341, 1341, 1341,
+ 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
+ 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367,
+ 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367,
+
+ 1367, 1367, 1367, 1367, 1367, 1341, 1341, 1367,
+ 1367, 1367, 1367, 1367, 1367, 192, 192, 192,
+ 1341, 1341, 1341, 1341, 1341, 1311, 1311, 1311,
+ 1311, 1311, 192, 192, 192, 192, 192, 192,
+
+ 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
+ 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
+ 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
+ 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
+
+ 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
+ 1385, 1385, 1385, 1385, 1385, 1385, 1385, 192,
1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
- 1386, 1386, 1386, 1386, 1387, 1388, 1389, 1390,
1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
+ 1386, 1386, 1386, 1386, 1386, 1386, 1386, 192,
+
+ 126, 122, 1387, 1388, 1389, 1390, 1391, 126,
+ 122, 126, 122, 126, 122, 1392, 1393, 1394,
+ 1395, 1056, 1058, 1059, 1396, 126, 122, 1396,
+ 1056, 1056, 1056, 1056, 1397, 1397, 1398, 1398,
+
+ 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
+ 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
+ 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
+ 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
+
+ 1399, 1400, 1399, 1400, 1401, 1402, 1402, 1402,
+ 1402, 1402, 1402, 1403, 1404, 1403, 1404, 1405,
+ 1405, 1405, 1406, 1407, 192, 192, 192, 192,
+ 192, 1408, 1409, 1409, 1409, 1410, 1408, 1409,
+
+ 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
+ 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
+ 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
+ 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
+
+ 1411, 1411, 1411, 1411, 1411, 1411, 192, 1412,
+ 192, 192, 192, 192, 192, 1412, 192, 192,
+ 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
+ 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
+
+ 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
+ 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
+ 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
+ 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
+
+ 1413, 1413, 1413, 1413, 1413, 1413, 1414, 1414,
+ 192, 192, 192, 192, 192, 192, 192, 1415,
+ 1416, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 1417,
+
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 798, 798, 798, 798, 798, 798, 798, 192,
+ 798, 798, 798, 798, 798, 798, 798, 192,
+ 798, 798, 798, 798, 798, 798, 798, 192,
+ 798, 798, 798, 798, 798, 798, 798, 192,
- 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398,
- 1399, 1400, 1386, 1386, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 240, 241, 240, 241, 240, 241, 240, 241,
- 240, 241, 240, 241, 240, 241, 240, 241,
- 240, 241, 240, 241, 240, 241, 240, 241,
- 240, 241, 240, 241, 240, 241, 240, 241,
-
- 244, 245, 240, 241, 240, 241, 240, 241,
- 240, 241, 240, 241, 240, 241, 1401, 228,
- 1402, 1402, 1402, 1403, 1404, 1404, 1404, 1404,
- 1404, 1404, 1404, 1404, 228, 228, 1403, 1405,
-
- 240, 241, 240, 241, 240, 241, 240, 241,
- 240, 241, 240, 241, 240, 241, 240, 241,
- 240, 241, 240, 241, 240, 241, 240, 241,
- 177, 177, 177, 177, 177, 177, 177, 1404,
-
- 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406,
- 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406,
- 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406,
- 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406,
-
- 1406, 1406, 1406, 1406, 1406, 1406, 1407, 1407,
- 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407,
- 1408, 1408, 1409, 1410, 1411, 1411, 1411, 1410,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412,
- 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412,
- 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1413,
- 1413, 1413, 1413, 1316, 1316, 1316, 1316, 1316,
-
- 1414, 1414, 995, 996, 995, 996, 995, 996,
- 995, 996, 995, 996, 995, 996, 995, 996,
- 993, 993, 995, 996, 995, 996, 995, 996,
- 995, 996, 995, 996, 995, 996, 995, 996,
-
- 995, 996, 995, 996, 995, 996, 995, 996,
- 995, 996, 995, 996, 995, 996, 995, 996,
- 995, 996, 995, 996, 995, 996, 995, 996,
- 995, 996, 995, 996, 995, 996, 995, 996,
-
- 995, 996, 995, 996, 995, 996, 995, 996,
- 995, 996, 995, 996, 995, 996, 995, 996,
- 1284, 993, 993, 993, 993, 993, 993, 993,
- 993, 995, 996, 995, 996, 1415, 995, 996,
-
- 995, 996, 995, 996, 995, 996, 995, 996,
- 1316, 1416, 1416, 995, 996, 1417, 1418, 177,
- 1419, 1420, 1421, 1422, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1419, 1420, 1419, 1420, 1419, 1420, 1419, 1420,
- 1419, 1420, 1423, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1424, 1424, 1418, 1425, 1425, 1425, 1425, 1425,
-
- 1426, 1426, 1427, 1426, 1426, 1426, 1428, 1426,
- 1426, 1426, 1426, 1427, 1426, 1426, 1426, 1426,
- 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
- 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
-
- 1426, 1426, 1426, 1429, 1429, 1427, 1427, 1429,
- 1430, 1430, 1430, 1430, 177, 177, 177, 177,
- 1367, 1367, 1367, 1367, 1367, 1367, 685, 685,
- 1155, 1431, 177, 177, 177, 177, 177, 177,
-
- 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
- 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
- 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
- 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
-
- 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
- 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432,
- 1432, 1432, 1432, 1432, 1433, 1433, 1434, 1434,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1435, 1435, 1436, 1436, 1436, 1436, 1436, 1436,
- 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436,
- 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436,
- 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436,
+ 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256,
- 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436,
- 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436,
- 1436, 1436, 1436, 1436, 1435, 1435, 1435, 1435,
- 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
+ 1418, 1418, 1419, 1420, 1419, 1420, 1418, 1418,
+ 1418, 1419, 1420, 1418, 1419, 1420, 1218, 1218,
+ 1218, 1218, 1218, 1218, 1218, 1218, 1217, 1421,
+ 1422, 1423, 1424, 1425, 1419, 1420, 1425, 1425,
- 1435, 1435, 1435, 1435, 1437, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 1438, 1438,
- 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446,
- 1447, 1448, 177, 177, 177, 177, 177, 177,
-
- 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449,
- 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449,
- 1449, 1449, 435, 435, 435, 435, 435, 435,
- 1450, 1450, 1450, 435, 177, 177, 177, 177,
-
- 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458,
- 1459, 1460, 1461, 1461, 1461, 1461, 1461, 1461,
- 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
- 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461,
-
- 1461, 1461, 1461, 1461, 1461, 1461, 1462, 1462,
- 1462, 1462, 1462, 1463, 1463, 1463, 1464, 1465,
- 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466,
- 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466,
-
- 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1467,
- 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467,
- 1467, 1467, 1468, 1469, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 1470,
-
- 733, 733, 733, 733, 733, 733, 733, 733,
- 733, 733, 733, 733, 733, 733, 733, 733,
- 733, 733, 733, 733, 733, 733, 733, 733,
- 733, 733, 733, 733, 733, 177, 177, 177,
-
- 1471, 1471, 1471, 1472, 1473, 1473, 1473, 1473,
- 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473,
- 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473,
- 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473,
-
- 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473,
- 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473,
- 1473, 1473, 1473, 1474, 1472, 1472, 1471, 1471,
- 1471, 1471, 1472, 1472, 1471, 1472, 1472, 1472,
-
- 1475, 1476, 1476, 1476, 1476, 1476, 1476, 1477,
- 1478, 1478, 1476, 1476, 1476, 1476, 177, 1479,
- 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487,
- 1488, 1489, 177, 177, 177, 177, 1476, 1476,
-
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
-
- 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
- 1490, 1491, 1491, 1491, 1491, 1491, 1491, 1492,
- 1492, 1491, 1491, 1492, 1492, 1491, 1491, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1490, 1490, 1490, 1491, 1490, 1490, 1490, 1490,
- 1490, 1490, 1490, 1490, 1491, 1492, 177, 177,
- 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500,
- 1501, 1502, 177, 177, 1503, 1504, 1504, 1504,
-
- 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
- 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
- 1506, 1505, 1505, 1505, 1505, 1505, 1505, 1507,
- 1507, 1507, 1505, 721, 177, 177, 177, 177,
-
- 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
- 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
- 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
- 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
-
- 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
- 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
- 1509, 1508, 1509, 1509, 1510, 1508, 1508, 1509,
- 1509, 1508, 1508, 1508, 1508, 1508, 1509, 1509,
-
- 1508, 1509, 1508, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 1508, 1508, 1511, 1512, 1512,
-
- 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513,
- 1513, 1513, 1513, 1514, 1515, 1515, 1514, 1514,
- 1516, 1516, 1513, 1517, 1517, 1514, 1518, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 1519, 1519, 1519, 1519, 1519, 1519, 177,
- 177, 1519, 1519, 1519, 1519, 1519, 1519, 177,
- 177, 1519, 1519, 1519, 1519, 1519, 1519, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1519, 1519, 1519, 1519, 1519, 1519, 1519, 177,
- 1519, 1519, 1519, 1519, 1519, 1519, 1519, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
- 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
- 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
- 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
-
- 1520, 1520, 1520, 1521, 1521, 1522, 1521, 1521,
- 1522, 1521, 1521, 1523, 1521, 1524, 177, 177,
- 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532,
- 1533, 1534, 177, 177, 177, 177, 177, 177,
-
- 1535, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1535, 1536, 1536, 1536,
-
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1535, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
-
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1535, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
-
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1535, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
-
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1535, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
-
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1535, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
-
- 1536, 1536, 1536, 1536, 1535, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
- 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536,
-
- 1536, 1536, 1536, 1536, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 735, 735, 735, 735, 735, 735, 735, 735,
- 735, 735, 735, 735, 735, 735, 735, 735,
-
- 735, 735, 735, 735, 735, 735, 735, 177,
- 177, 177, 177, 737, 737, 737, 737, 737,
- 737, 737, 737, 737, 737, 737, 737, 737,
- 737, 737, 737, 737, 737, 737, 737, 737,
-
- 737, 737, 737, 737, 737, 737, 737, 737,
- 737, 737, 737, 737, 737, 737, 737, 737,
- 737, 737, 737, 737, 737, 737, 737, 737,
- 737, 737, 737, 737, 177, 177, 177, 177,
-
- 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537,
- 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537,
- 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537,
- 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537,
-
- 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538,
- 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538,
- 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538,
- 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538,
-
- 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373,
- 1373, 1373, 1373, 1373, 1373, 1373, 1377, 1377,
- 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539,
- 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539,
-
- 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539,
- 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539,
- 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539,
- 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539,
-
- 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539,
- 1539, 1539, 1539, 1376, 1376, 1376, 1372, 1372,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
+ 1426, 1427, 1372, 1373, 1372, 1373, 1372, 1373,
+ 1372, 1373, 1423, 1423, 1423, 1423, 1428, 1429,
+ 1423, 1430, 1431, 1432, 1432, 1431, 1431, 1431,
+ 1431, 1431, 1433, 1433, 192, 192, 192, 192,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 192, 1434, 1434, 1434, 1434, 1435,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1540, 1541, 1542, 1543, 1544, 1545, 1545, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 1546, 1547, 1548, 1549, 1550,
- 177, 177, 177, 177, 177, 1551, 1552, 283,
-
- 283, 283, 283, 283, 283, 283, 283, 283,
- 283, 1553, 283, 283, 283, 283, 283, 283,
- 283, 283, 283, 283, 283, 283, 283, 256,
- 283, 283, 283, 283, 283, 256, 283, 256,
-
- 283, 283, 256, 283, 283, 256, 283, 283,
- 283, 283, 283, 283, 283, 283, 283, 283,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
-
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
-
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 1554, 1554, 1554, 1554, 1554, 1554,
- 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554,
-
- 1554, 1554, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
-
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 1105, 1331,
-
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
-
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 288, 288, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
-
- 304, 304, 304, 304, 304, 304, 304, 304,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555,
- 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555,
-
- 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555,
- 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 1556, 1177, 288, 288,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
+ 1434, 1434, 1434, 1435, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
+ 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
+ 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
+ 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
+
+ 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
+ 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
+ 1435, 1435, 1435, 1435, 1435, 1435, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436,
+ 1436, 1436, 1436, 1436, 192, 192, 192, 192,
+
+ 1437, 1438, 1439, 1440, 1304, 1441, 1442, 1443,
+ 16, 1209, 16, 1209, 16, 1209, 16, 1209,
+ 16, 1209, 1304, 1304, 16, 1209, 16, 1209,
+ 16, 1209, 16, 1209, 1444, 1187, 1445, 1445,
+
+ 1304, 1443, 1443, 1443, 1443, 1443, 1443, 1443,
+ 1443, 1443, 1446, 1447, 164, 1448, 1449, 1449,
+ 1450, 1451, 1451, 1451, 1451, 1451, 1452, 1304,
+ 1453, 1453, 1453, 1454, 1455, 1456, 1436, 1304,
+
+ 192, 1457, 1458, 1457, 1458, 1457, 1458, 1457,
+ 1458, 1457, 1458, 1458, 1459, 1458, 1459, 1458,
+ 1459, 1458, 1459, 1458, 1459, 1458, 1459, 1458,
+ 1459, 1458, 1459, 1458, 1459, 1458, 1459, 1458,
+
+ 1459, 1458, 1459, 1457, 1458, 1459, 1458, 1459,
+ 1458, 1459, 1458, 1458, 1458, 1458, 1458, 1458,
+ 1459, 1459, 1458, 1459, 1459, 1458, 1459, 1459,
+ 1458, 1459, 1459, 1458, 1459, 1459, 1458, 1458,
+
+ 1458, 1458, 1458, 1457, 1458, 1457, 1458, 1457,
+ 1458, 1458, 1458, 1458, 1458, 1458, 1457, 1458,
+ 1458, 1458, 1458, 1458, 1459, 1460, 1460, 192,
+ 192, 1461, 1461, 1462, 1462, 1463, 1464, 1465,
+
+ 1466, 1467, 1468, 1467, 1468, 1467, 1468, 1467,
+ 1468, 1467, 1468, 1468, 1469, 1468, 1469, 1468,
+ 1469, 1468, 1469, 1468, 1469, 1468, 1469, 1468,
+ 1469, 1468, 1469, 1468, 1469, 1468, 1469, 1468,
+
+ 1469, 1468, 1469, 1467, 1468, 1469, 1468, 1469,
+ 1468, 1469, 1468, 1468, 1468, 1468, 1468, 1468,
+ 1469, 1469, 1468, 1469, 1469, 1468, 1469, 1469,
+ 1468, 1469, 1469, 1468, 1469, 1469, 1468, 1468,
+
+ 1468, 1468, 1468, 1467, 1468, 1467, 1468, 1467,
+ 1468, 1468, 1468, 1468, 1468, 1468, 1467, 1468,
+ 1468, 1468, 1468, 1468, 1469, 1467, 1467, 1469,
+ 1469, 1469, 1469, 1470, 1471, 1472, 1473, 1474,
+
+ 192, 192, 192, 192, 192, 1475, 1475, 1475,
+ 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
+ 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
+ 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
+
+ 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
+ 1475, 1475, 1475, 1475, 1475, 1476, 192, 192,
+ 192, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
+ 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
+
+ 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
+ 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
+ 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
+ 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
+
+ 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
+ 1477, 1477, 1477, 1477, 1477, 1477, 1477, 192,
+ 1478, 1478, 1479, 1479, 1479, 1479, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+
+ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481,
+ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481,
+ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481,
+ 1482, 1482, 1482, 192, 192, 192, 192, 192,
+
+ 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340,
+ 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+
+ 1344, 1344, 1344, 1344, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483,
+ 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483,
+
+ 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
+ 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
+ 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
+ 1484, 1484, 1484, 1484, 1484, 1485, 1485, 192,
+
+ 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479,
+ 1479, 1479, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+
+ 1480, 1480, 1480, 1480, 1486, 1486, 1486, 1486,
+ 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487,
+ 1488, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
+ 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
+
+ 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
+ 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
+ 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
+ 1484, 1484, 1484, 1484, 1485, 1485, 1490, 1478,
+
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
+ 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
+
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1488, 1488, 1488, 1488,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 192,
+
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1488,
+ 1488, 1488, 1488, 1480, 1480, 1480, 1480, 1480,
+
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1488, 1488,
+
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
+ 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1488,
+
+ 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
+ 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
+ 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
+ 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
+
+ 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
+ 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
+ 1492, 1492, 1492, 1492, 1492, 1492, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+
+ 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+ 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+ 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+ 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+
+ 1494, 1494, 1494, 1494, 1494, 1494, 1495, 1495,
+ 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495,
+ 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495,
+ 1495, 1495, 1495, 1495, 1496, 1496, 1496, 1496,
+
+ 1496, 1496, 1496, 1496, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1498, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1500, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 192, 192, 192,
+ 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
+ 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
+
+ 1501, 1501, 1502, 1502, 1501, 1501, 1501, 1501,
+ 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
+ 1501, 1501, 1501, 1501, 1502, 1501, 1501, 1501,
+ 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
+
+ 1501, 1502, 1501, 1501, 1501, 1502, 1501, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
+ 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
+
+ 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
+ 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
+ 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1505, 1506,
+
+ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+
+ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+ 1507, 1507, 1507, 1507, 1508, 1509, 1510, 1511,
+ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+
+ 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519,
+ 1520, 1521, 1507, 1507, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 270, 271, 270, 271, 270, 271, 270, 271,
+ 270, 271, 270, 271, 270, 271, 270, 271,
+ 270, 271, 270, 271, 270, 271, 270, 271,
+ 270, 271, 270, 271, 270, 271, 270, 271,
+
+ 274, 275, 270, 271, 270, 271, 270, 271,
+ 270, 271, 270, 271, 270, 271, 1522, 256,
+ 1523, 1523, 1523, 1524, 1525, 1525, 1525, 1525,
+ 1525, 1525, 1525, 1525, 256, 256, 1524, 1526,
+
+ 270, 271, 270, 271, 270, 271, 270, 271,
+ 270, 271, 270, 271, 270, 271, 270, 271,
+ 270, 271, 270, 271, 270, 271, 270, 271,
+ 192, 192, 192, 192, 192, 192, 192, 1525,
+
+ 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
+ 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
+ 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
+ 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
+
+ 1527, 1527, 1527, 1527, 1527, 1527, 1528, 1528,
+ 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528,
+ 1529, 1529, 1530, 1531, 1532, 1532, 1532, 1531,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533,
+ 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533,
+ 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1534,
+ 1534, 1534, 1534, 1429, 1429, 1429, 1429, 1429,
+
+ 1535, 1535, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1056, 1056, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1397, 1056, 1056, 1056, 1056, 1056, 1056, 1056,
+ 1056, 1058, 1059, 1058, 1059, 1536, 1058, 1059,
+
+ 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
+ 1429, 1537, 1537, 1058, 1059, 1538, 1539, 192,
+ 1540, 1541, 1542, 1543, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1540, 1541, 1540, 1541, 1540, 1541, 1540, 1541,
+ 1540, 1541, 1544, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1545, 1545, 1539, 1546, 1546, 1546, 1546, 1546,
+
+ 1547, 1547, 1548, 1547, 1547, 1547, 1549, 1547,
+ 1547, 1547, 1547, 1548, 1547, 1547, 1547, 1547,
+ 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547,
+ 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547,
+
+ 1547, 1547, 1547, 1550, 1550, 1548, 1548, 1550,
+ 1551, 1551, 1551, 1551, 192, 192, 192, 192,
+ 1487, 1487, 1487, 1487, 1487, 1487, 740, 740,
+ 1245, 1552, 192, 192, 192, 192, 192, 192,
+
+ 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
+ 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
+ 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
+ 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
+
+ 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
+ 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
+ 1553, 1553, 1553, 1553, 1554, 1554, 1555, 1555,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1556, 1556, 1557, 1557, 1557, 1557, 1557, 1557,
+ 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
+ 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
+ 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
- 1558, 1559, 1560, 1561, 1562, 1563, 1563, 1564,
- 1565, 1566, 177, 177, 177, 177, 177, 177,
-
- 153, 153, 153, 153, 981, 981, 981, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1326, 1567, 1567, 1568, 1568, 1105, 1331, 1105,
- 1331, 1105, 1331, 1105, 1331, 1105, 1331, 1105,
-
- 1331, 1105, 1331, 1105, 1331, 1341, 1341, 1569,
- 1570, 1326, 1326, 1326, 1326, 1568, 1568, 1568,
- 1571, 1572, 1573, 177, 1574, 1575, 9, 9,
- 1567, 16, 1124, 16, 1124, 16, 1124, 1576,
-
- 1326, 1326, 1577, 1578, 1579, 1580, 1581, 177,
- 1326, 12, 13, 1326, 177, 177, 177, 177,
- 304, 304, 304, 1582, 304, 288, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
-
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 288, 288, 1583,
-
- 177, 9, 1326, 1576, 12, 13, 1326, 1584,
- 16, 1124, 1326, 1577, 1571, 1578, 1573, 1585,
- 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593,
- 1594, 1595, 1575, 1574, 1596, 1581, 1597, 9,
-
- 1326, 1598, 1598, 1598, 1598, 1598, 1598, 1598,
- 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598,
- 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598,
- 1598, 1598, 1598, 39, 1326, 46, 1599, 1568,
-
- 1599, 1600, 1600, 1600, 1600, 1600, 1600, 1600,
- 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600,
- 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600,
- 1600, 1600, 1600, 39, 1581, 46, 1581, 1245,
-
- 1246, 1325, 16, 1124, 1324, 1352, 1601, 1350,
- 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350,
- 1353, 1601, 1601, 1601, 1601, 1601, 1601, 1601,
- 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601,
-
- 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601,
- 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601,
- 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601,
- 1601, 1601, 1601, 1601, 1601, 1601, 1602, 1602,
-
- 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603,
- 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603,
- 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603,
- 1603, 1603, 1603, 1603, 1603, 1603, 1603, 177,
-
- 177, 177, 1603, 1603, 1603, 1603, 1603, 1603,
- 177, 177, 1603, 1603, 1603, 1603, 1603, 1603,
- 177, 177, 1603, 1603, 1603, 1603, 1603, 1603,
- 177, 177, 1603, 1603, 1603, 177, 177, 177,
-
- 50, 12, 1581, 1599, 1206, 12, 12, 177,
- 51, 36, 36, 36, 36, 51, 51, 177,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1604, 1604, 1604, 1605, 51, 1606, 1606,
-
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 177, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
-
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 177,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 177, 1607, 1607, 177, 1607,
-
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 177, 177,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 177, 177,
-
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
-
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607,
- 1607, 1607, 1607, 177, 177, 177, 177, 177,
-
- 1608, 1609, 1608, 177, 177, 177, 177, 1610,
- 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610,
- 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610,
- 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610,
-
- 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610,
- 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610,
- 1610, 1610, 1610, 1610, 177, 177, 177, 1611,
+ 1557, 1557, 1557, 1557, 1556, 1556, 1556, 1556,
+ 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556,
+
+ 1556, 1556, 1556, 1556, 1558, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 1559, 1559,
+ 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567,
+ 1568, 1569, 192, 192, 192, 192, 192, 192,
+
+ 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570,
+ 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570,
+ 1570, 1570, 473, 473, 473, 473, 473, 473,
+ 1571, 1571, 1571, 473, 192, 192, 192, 192,
+
+ 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579,
+ 1580, 1581, 1582, 1582, 1582, 1582, 1582, 1582,
+ 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582,
+ 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582,
+
+ 1582, 1582, 1582, 1582, 1582, 1582, 1583, 1583,
+ 1583, 1583, 1583, 1584, 1584, 1584, 1585, 1586,
+ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
+ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
+
+ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1588,
+ 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588,
+ 1588, 1588, 1589, 1590, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 1591,
+
+ 790, 790, 790, 790, 790, 790, 790, 790,
+ 790, 790, 790, 790, 790, 790, 790, 790,
+ 790, 790, 790, 790, 790, 790, 790, 790,
+ 790, 790, 790, 790, 790, 192, 192, 192,
+
+ 1592, 1592, 1592, 1593, 1594, 1594, 1594, 1594,
+ 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
+ 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
+ 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
+
+ 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
+ 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
+ 1594, 1594, 1594, 1595, 1593, 1593, 1592, 1592,
+ 1592, 1592, 1593, 1593, 1592, 1593, 1593, 1593,
+
+ 1596, 1597, 1597, 1597, 1597, 1597, 1597, 1598,
+ 1599, 1599, 1597, 1597, 1597, 1597, 192, 1600,
+ 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608,
+ 1609, 1610, 192, 192, 192, 192, 1597, 1597,
+
+ 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
+ 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
+ 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
- 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612,
- 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612,
- 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612,
- 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612,
-
- 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612,
- 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612,
- 1612, 1612, 1612, 1612, 1612, 1613, 1613, 1613,
- 1613, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
-
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1613, 177, 177, 177, 177, 177,
- 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239,
- 1239, 1239, 1239, 1239, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185,
- 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185,
-
- 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185,
- 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185,
- 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185,
- 1185, 1185, 1185, 1185, 1185, 984, 177, 177,
-
- 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615,
- 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615,
- 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615,
- 1615, 1615, 1615, 1615, 1615, 177, 177, 177,
-
- 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616,
- 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616,
- 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616,
- 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616,
-
- 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616,
- 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616,
- 1616, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617,
- 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617,
- 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617,
- 1617, 1617, 1617, 1617, 1617, 1617, 1617, 177,
-
- 1618, 1618, 1618, 1618, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619,
- 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619,
-
- 1619, 1620, 1619, 1619, 1619, 1619, 1619, 1619,
- 1619, 1619, 1620, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621,
- 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621,
- 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621,
- 1621, 1621, 1621, 1621, 1621, 1621, 177, 1622,
-
- 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623,
- 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623,
- 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623,
- 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623,
-
- 1623, 1623, 1623, 1623, 177, 177, 177, 177,
- 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623,
- 1624, 1625, 1625, 1625, 1625, 1625, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
+ 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
+ 1611, 1612, 1612, 1612, 1612, 1612, 1612, 1613,
+ 1613, 1612, 1612, 1613, 1613, 1612, 1612, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1611, 1611, 1611, 1612, 1611, 1611, 1611, 1611,
+ 1611, 1611, 1611, 1611, 1612, 1613, 192, 192,
+ 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621,
+ 1622, 1623, 192, 192, 1624, 1625, 1625, 1625,
1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
- 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
- 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
-
- 1626, 1626, 1626, 1626, 1626, 1626, 1627, 1627,
- 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628,
- 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628,
- 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628,
-
- 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628,
- 1628, 1628, 1628, 1628, 1628, 1628, 1629, 1629,
- 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
- 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
-
- 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
- 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
- 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
- 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630,
-
- 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631,
- 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631,
- 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631,
- 1631, 1631, 1631, 1631, 1631, 1631, 177, 177,
-
- 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639,
- 1640, 1641, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1642, 1642, 1642, 1642, 1642, 1642, 256, 256,
- 1642, 256, 1642, 1642, 1642, 1642, 1642, 1642,
- 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642,
- 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642,
-
- 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642,
- 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642,
- 1642, 1642, 1642, 1642, 1642, 1642, 256, 1642,
- 1642, 256, 256, 256, 1642, 256, 256, 1642,
-
- 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643,
- 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643,
- 1643, 1643, 1643, 1643, 1643, 1643, 256, 1644,
- 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645,
-
- 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646,
- 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646,
- 1646, 1646, 1646, 1646, 1646, 1646, 1647, 1647,
- 1647, 1647, 1648, 1648, 256, 256, 256, 1649,
-
- 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650,
- 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650,
- 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650,
- 1650, 1650, 256, 256, 256, 256, 256, 1651,
-
- 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652,
- 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652,
- 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652,
- 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652,
-
- 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653,
- 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653,
- 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653,
- 256, 256, 256, 256, 256, 256, 1653, 1653,
-
- 1654, 1655, 1655, 1655, 256, 1655, 1655, 256,
- 256, 256, 256, 256, 1655, 1656, 1655, 1657,
- 1654, 1654, 1654, 1654, 256, 1654, 1654, 1654,
- 256, 1654, 1654, 1654, 1654, 1654, 1654, 1654,
-
- 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654,
- 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654,
- 1654, 1654, 1654, 1654, 256, 256, 256, 256,
- 1657, 1658, 1656, 256, 256, 256, 256, 1659,
-
- 1660, 1661, 1662, 1663, 1664, 1664, 1664, 1664,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 1665, 1665, 1665, 1665, 1665, 1665, 1666, 1666,
- 1667, 256, 256, 256, 256, 256, 256, 256,
-
- 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668,
- 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668,
- 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668,
- 1668, 1668, 1668, 1668, 1668, 1669, 1669, 1670,
-
- 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
- 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
- 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
- 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
-
- 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
- 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671,
- 1671, 1671, 1671, 1671, 1671, 1671, 256, 256,
- 256, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
-
- 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673,
- 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673,
- 1673, 1673, 1673, 1673, 1673, 1673, 256, 256,
- 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674,
-
- 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675,
- 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675,
- 1675, 1675, 1675, 256, 256, 256, 256, 256,
- 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676,
-
- 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
- 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
- 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
- 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
-
- 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
- 1677, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
-
- 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685,
- 1686, 1687, 1687, 1687, 1687, 1687, 1687, 1687,
- 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687,
- 1687, 1687, 1687, 1687, 1687, 1687, 1687, 256,
-
- 1688, 1689, 1688, 1690, 1690, 1690, 1690, 1690,
- 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690,
- 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690,
- 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690,
- 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690,
- 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690,
- 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690,
- 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689,
- 1689, 1689, 1689, 1689, 1689, 1689, 1691, 1692,
- 1692, 1693, 1693, 1693, 1693, 1693, 177, 177,
- 177, 177, 1694, 1695, 1696, 1697, 1698, 1699,
- 1700, 1701, 1702, 1703, 1703, 1703, 1703, 1703,
- 1703, 1703, 1703, 1703, 1703, 1703, 1704, 1705,
- 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1714, 1714, 1715, 1716, 1716, 1716, 1716, 1716,
- 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716,
- 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716,
- 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716,
- 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716,
- 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716,
- 1715, 1715, 1715, 1714, 1714, 1714, 1714, 1715,
- 1715, 1717, 1718, 1719, 1719, 1720, 1721, 1721,
- 1721, 1721, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722,
- 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722,
- 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722,
- 1722, 177, 177, 177, 177, 177, 177, 177,
- 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730,
- 1731, 1732, 177, 177, 177, 177, 177, 177,
-
- 1733, 1733, 1733, 1734, 1734, 1734, 1734, 1734,
+ 1627, 1626, 1626, 1626, 1626, 1626, 1626, 1628,
+ 1628, 1628, 1626, 778, 192, 192, 192, 192,
+
+ 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
+ 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
+ 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
+ 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
+
+ 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
+ 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
+ 1630, 1629, 1630, 1630, 1631, 1629, 1629, 1630,
+ 1630, 1629, 1629, 1629, 1629, 1629, 1630, 1630,
+
+ 1629, 1630, 1629, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 1629, 1629, 1632, 1633, 1633,
+
+ 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634,
+ 1634, 1634, 1634, 1635, 1636, 1636, 1635, 1635,
+ 1637, 1637, 1634, 1638, 1638, 1635, 1639, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 1640, 1640, 1640, 1640, 1640, 1640, 192,
+ 192, 1640, 1640, 1640, 1640, 1640, 1640, 192,
+ 192, 1640, 1640, 1640, 1640, 1640, 1640, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1640, 1640, 1640, 1640, 1640, 1640, 1640, 192,
+ 1640, 1640, 1640, 1640, 1640, 1640, 1640, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
+ 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
+ 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
+ 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
+
+ 1641, 1641, 1641, 1642, 1642, 1643, 1642, 1642,
+ 1643, 1642, 1642, 1644, 1642, 1645, 192, 192,
+ 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653,
+ 1654, 1655, 192, 192, 192, 192, 192, 192,
+
+ 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
+
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+
+ 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
+
+ 1657, 1657, 1657, 1657, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 793, 793, 793, 793, 793, 793, 793, 793,
+ 793, 793, 793, 793, 793, 793, 793, 793,
+
+ 793, 793, 793, 793, 793, 793, 793, 192,
+ 192, 192, 192, 796, 796, 796, 796, 796,
+ 796, 796, 796, 796, 796, 796, 796, 796,
+ 796, 796, 796, 796, 796, 796, 796, 796,
+
+ 796, 796, 796, 796, 796, 796, 796, 796,
+ 796, 796, 796, 796, 796, 796, 796, 796,
+ 796, 796, 796, 796, 796, 796, 796, 796,
+ 796, 796, 796, 796, 192, 192, 192, 192,
+
+ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
+ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
+ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
+ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
+
+ 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
+ 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
+ 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
+ 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
+
+ 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
+ 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
+ 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
+ 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
+
+ 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
+ 1660, 1660, 1660, 1660, 1660, 1660, 1494, 1494,
+ 1660, 1494, 1660, 1494, 1494, 1660, 1660, 1660,
+ 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1494,
+
+ 1660, 1494, 1660, 1494, 1494, 1660, 1660, 1494,
+ 1494, 1494, 1660, 1660, 1660, 1660, 1661, 1661,
+ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
+ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
+
+ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
+ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
+ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
+ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
+
+ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
+ 1662, 1662, 1662, 1663, 1663, 1663, 1493, 1493,
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+ 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
+ 1664, 1664, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1665, 1666, 1667, 1668, 1669, 1670, 1670, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 1671, 1672, 1673, 1674, 1675,
+ 192, 192, 192, 192, 192, 1676, 1677, 1678,
+
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1680, 1678, 1678, 1678, 1678, 1678, 1678,
+ 1678, 1678, 1678, 1678, 1678, 1678, 1678, 286,
+ 1678, 1678, 1678, 1678, 1678, 286, 1678, 286,
+
+ 1678, 1678, 286, 1678, 1678, 286, 1678, 1678,
+ 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1679,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1682, 1682, 1682, 1682, 1682, 1682,
+ 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682,
+
+ 1682, 1682, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1187, 1445,
+
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 318, 318, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
+ 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
+
+ 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
+ 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1684, 1309, 318, 318,
+
+ 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685,
+ 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685,
+ 1686, 1687, 1688, 1689, 1690, 1691, 1691, 1692,
+ 1693, 1694, 192, 192, 192, 192, 192, 192,
+
+ 163, 163, 163, 163, 1044, 1044, 1044, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1695, 1696, 1696, 1697, 1697, 1698, 1699, 1698,
+ 1699, 1698, 1699, 1698, 1699, 1698, 1699, 1698,
+
+ 1699, 1698, 1699, 1698, 1699, 1456, 1456, 1700,
+ 1701, 1695, 1695, 1695, 1695, 1697, 1697, 1697,
+ 1702, 1703, 1704, 192, 1705, 1706, 1707, 1707,
+ 1696, 1236, 1237, 1236, 1237, 1236, 1237, 1708,
+
+ 1695, 1695, 1709, 1710, 1711, 1712, 1713, 192,
+ 1695, 1239, 1201, 1695, 192, 192, 192, 192,
+ 1681, 1681, 1681, 1714, 1681, 318, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
+ 1681, 1681, 1681, 1681, 1681, 318, 318, 1715,
+
+ 192, 1707, 1695, 1708, 1239, 1201, 1695, 1716,
+ 1236, 1237, 1695, 1709, 1702, 1710, 1704, 1717,
+ 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725,
+ 1726, 1727, 1706, 1705, 1728, 1713, 1729, 1707,
+
+ 1695, 1730, 1730, 1730, 1730, 1730, 1730, 1730,
+ 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730,
+ 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730,
+ 1730, 1730, 1730, 1731, 1695, 1732, 1733, 1697,
+
+ 1733, 1734, 1734, 1734, 1734, 1734, 1734, 1734,
1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734,
1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734,
- 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734,
- 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1735,
- 1735, 1735, 1735, 1735, 1736, 1735, 1735, 1735,
- 1735, 1735, 1735, 1737, 1737, 177, 1738, 1739,
- 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747,
- 1748, 1749, 1749, 1749, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1750, 1750, 1751, 1752, 1752, 1752, 1752, 1752,
+ 1734, 1734, 1734, 1731, 1713, 1732, 1713, 1735,
+
+ 1736, 1737, 1236, 1237, 1738, 1739, 1740, 1741,
+ 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
+ 1742, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
+ 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
+
+ 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
+ 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
+ 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
+ 1740, 1740, 1740, 1740, 1740, 1740, 1743, 1743,
+
+ 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744,
+ 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744,
+ 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744,
+ 1744, 1744, 1744, 1744, 1744, 1744, 1744, 192,
+
+ 192, 192, 1744, 1744, 1744, 1744, 1744, 1744,
+ 192, 192, 1744, 1744, 1744, 1744, 1744, 1744,
+ 192, 192, 1744, 1744, 1744, 1744, 1744, 1744,
+ 192, 192, 1744, 1744, 1744, 192, 192, 192,
+
+ 1745, 1239, 1713, 1733, 1452, 1239, 1239, 192,
+ 1255, 1235, 1235, 1235, 1235, 1255, 1255, 192,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1746, 1746, 1746, 1747, 51, 1748, 1748,
+
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 192, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 192,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 192, 1749, 1749, 192, 1749,
+
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 192, 192,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 192, 192,
+
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1749, 1749, 1749, 192, 192, 192, 192, 192,
+
+ 1750, 1751, 1750, 192, 192, 192, 192, 1752,
1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
+
1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
- 1752, 1752, 1752, 1751, 1751, 1751, 1750, 1750,
- 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1751,
- 1753, 1752, 1752, 1752, 1752, 1754, 1754, 1755,
- 1756, 177, 177, 177, 177, 177, 177, 177,
- 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764,
- 1765, 1766, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
- 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
- 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
- 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
- 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
- 1767, 1767, 1767, 1768, 1769, 1768, 1769, 1769,
- 1768, 1768, 1768, 1768, 1768, 1768, 1770, 1771,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779,
- 1780, 1781, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
-
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1782, 1782, 1782, 1782, 1782, 1782, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
- 1783, 1783, 1783, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1784, 1784, 1784, 1784, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
-
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1786, 1786, 1786, 1787, 1787, 1787, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1787, 1785, 1785, 1785, 1786, 1787,
- 1786, 1787, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
+ 1752, 1752, 1752, 1752, 192, 192, 192, 1753,
+ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753,
+
+ 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
+ 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
+ 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
+ 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
+
+ 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
+ 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
+ 1754, 1754, 1754, 1754, 1754, 1755, 1755, 1755,
+ 1755, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1755, 192, 192, 192, 192, 192,
+ 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
+ 1341, 1341, 1341, 1341, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
+
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1277, 1047, 192, 192,
+
+ 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757,
+ 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757,
+ 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757,
+ 1757, 1757, 1757, 1757, 1757, 192, 192, 192,
+
+ 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
+ 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
+ 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
+ 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
+
+ 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
+ 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
+ 1758, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759,
+ 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759,
+ 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759,
+ 1759, 1759, 1759, 1759, 1759, 1759, 1759, 192,
+
+ 1760, 1760, 1760, 1760, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761,
+ 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761,
+
+ 1761, 1762, 1761, 1761, 1761, 1761, 1761, 1761,
+ 1761, 1761, 1762, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763,
+ 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763,
+ 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763,
+ 1763, 1763, 1763, 1763, 1763, 1763, 192, 1764,
+
+ 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
+ 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
+ 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
+ 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
+
+ 1765, 1765, 1765, 1765, 192, 192, 192, 192,
+ 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
+ 1766, 1767, 1767, 1767, 1767, 1767, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
+ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
+ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
+ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
+
+ 1768, 1768, 1768, 1768, 1768, 1768, 1769, 1769,
+ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
+ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
+ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
+
+ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
+ 1770, 1770, 1770, 1770, 1770, 1770, 1771, 1771,
+ 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+ 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+
+ 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+ 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+ 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+ 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+
+ 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
+ 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
+ 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
+ 1773, 1773, 1773, 1773, 1773, 1773, 192, 192,
+
+ 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781,
+ 1782, 1783, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1784, 1784, 1784, 1784, 1784, 1784, 286, 286,
+ 1784, 286, 1784, 1784, 1784, 1784, 1784, 1784,
+ 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
+ 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
+
+ 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
+ 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
+ 1784, 1784, 1784, 1784, 1784, 1784, 286, 1784,
+ 1784, 286, 286, 286, 1784, 286, 286, 1784,
1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1786, 1787, 1787, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
+ 1785, 1785, 1785, 1785, 1785, 1785, 286, 1786,
+ 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 1785, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
+ 1788, 1788, 1788, 1788, 1788, 1788, 1789, 1789,
+ 1789, 1789, 1790, 1790, 286, 286, 286, 1791,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789,
- 1789, 1789, 1789, 1789, 1789, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1789, 1790, 1790, 1790, 1790, 1790, 1790, 1790,
- 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790,
- 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790,
- 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790,
- 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790,
- 1790, 1790, 1790, 1790, 1790, 1790, 1790, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 1791,
- 1791, 1791, 1791, 1792, 1792, 1792, 1792, 1792,
1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1793, 1794, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 286, 286, 286, 286, 286, 1793,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
+ 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
+ 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
+ 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
+ 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 177,
- 177, 1185, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1796, 1797, 1798,
- 1798, 1798, 1795, 1795, 1795, 1799, 1796, 1796,
- 1796, 1796, 1796, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1801, 1801, 1801, 1801, 1801,
- 1801, 1801, 1801, 1795, 1795, 1802, 1802, 1802,
- 1802, 1802, 1801, 1801, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1802, 1802, 1802, 1802, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614,
- 1614, 1614, 1803, 1803, 1803, 1614, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
- 1177, 1177, 1177, 1177, 1177, 1177, 1177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804,
- 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804,
- 1804, 1804, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 177, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1805, 177, 1805, 1805,
- 177, 177, 1805, 177, 177, 1805, 1805, 177,
- 177, 1805, 1805, 1805, 1805, 177, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1806, 1806,
- 1806, 1806, 177, 1806, 177, 1806, 1806, 1806,
- 1806, 1807, 1806, 1806, 177, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
-
- 1806, 1806, 1806, 1806, 1805, 1805, 177, 1805,
- 1805, 1805, 1805, 177, 177, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 177, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 177, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1805, 1805, 177, 1805, 1805, 1805, 1805, 177,
- 1805, 1805, 1805, 1805, 1805, 177, 1805, 177,
- 177, 177, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 177, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
-
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1178, 1178, 177, 177,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1808, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1809, 1806, 1806, 1806, 1806,
- 1806, 1806, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1808, 1806, 1806, 1806, 1806,
-
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1809, 1806, 1806,
- 1806, 1806, 1806, 1806, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1808, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1809,
- 1806, 1806, 1806, 1806, 1806, 1806, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1808,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1809, 1806, 1806, 1806, 1806, 1806, 1806,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805,
- 1805, 1808, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806,
- 1806, 1806, 1806, 1809, 1806, 1806, 1806, 1806,
- 1806, 1806, 1810, 1811, 177, 177, 1812, 1813,
- 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821,
- 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819,
- 1820, 1821, 1812, 1813, 1814, 1815, 1816, 1817,
- 1818, 1819, 1820, 1821, 1812, 1813, 1814, 1815,
- 1816, 1817, 1818, 1819, 1820, 1821, 1812, 1813,
- 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821,
+ 286, 286, 286, 286, 286, 286, 1795, 1795,
+
+ 1796, 1797, 1797, 1797, 286, 1797, 1797, 286,
+ 286, 286, 286, 286, 1797, 1798, 1797, 1799,
+ 1796, 1796, 1796, 1796, 286, 1796, 1796, 1796,
+ 286, 1796, 1796, 1796, 1796, 1796, 1796, 1796,
+
+ 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796,
+ 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796,
+ 1796, 1796, 1796, 1796, 286, 286, 286, 286,
+ 1799, 1800, 1798, 286, 286, 286, 286, 1801,
+
+ 1802, 1803, 1804, 1805, 1806, 1806, 1806, 1806,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 1807, 1807, 1807, 1807, 1807, 1807, 1808, 1808,
+ 1809, 286, 286, 286, 286, 286, 286, 286,
+
+ 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810,
+ 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810,
+ 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810,
+ 1810, 1810, 1810, 1810, 1810, 1811, 1811, 1812,
+
+ 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
+ 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
+ 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
+ 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
+
+ 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
+ 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
+ 1813, 1813, 1813, 1813, 1813, 1813, 286, 286,
+ 286, 1814, 1814, 1814, 1814, 1814, 1814, 1814,
+
+ 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815,
+ 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815,
+ 1815, 1815, 1815, 1815, 1815, 1815, 286, 286,
+ 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816,
+
+ 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817,
+ 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817,
+ 1817, 1817, 1817, 286, 286, 286, 286, 286,
+ 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818,
+
+ 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
+ 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
+ 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
+ 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
+
+ 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
+ 1819, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+
+ 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827,
+ 1828, 1829, 1829, 1829, 1829, 1829, 1829, 1829,
+ 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829,
+ 1829, 1829, 1829, 1829, 1829, 1829, 1829, 286,
+
+ 1830, 1831, 1830, 1832, 1832, 1832, 1832, 1832,
+ 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
+ 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
+ 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
+ 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
+ 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
+ 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
+ 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831,
+ 1831, 1831, 1831, 1831, 1831, 1831, 1833, 1834,
+ 1834, 1835, 1835, 1835, 1835, 1835, 192, 192,
+ 192, 192, 1836, 1837, 1838, 1839, 1840, 1841,
+ 1842, 1843, 1844, 1845, 1845, 1845, 1845, 1845,
+ 1845, 1845, 1845, 1845, 1845, 1845, 1846, 1847,
+ 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1856, 1856, 1857, 1858, 1858, 1858, 1858, 1858,
+ 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
+ 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
+ 1858, 1858, 1859, 1858, 1859, 1858, 1858, 1858,
+ 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
+ 1858, 1858, 1858, 1859, 1858, 1858, 1858, 1858,
+ 1857, 1857, 1857, 1856, 1856, 1856, 1856, 1857,
+ 1857, 1860, 1861, 1862, 1862, 1863, 1864, 1864,
+ 1864, 1864, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,
+ 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,
+ 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,
+ 1865, 192, 192, 192, 192, 192, 192, 192,
+ 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873,
+ 1874, 1875, 192, 192, 192, 192, 192, 192,
+
+ 1876, 1876, 1876, 1877, 1877, 1877, 1877, 1877,
+ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1878,
+ 1879, 1879, 1879, 1879, 1880, 1879, 1881, 1881,
+ 1879, 1879, 1879, 1882, 1882, 192, 1883, 1884,
+ 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892,
+ 1893, 1894, 1894, 1894, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1895, 1895, 1896, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1896, 1896, 1896, 1895, 1895,
+ 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1896,
+ 1898, 1897, 1897, 1897, 1897, 1899, 1899, 1900,
+ 1901, 192, 192, 192, 192, 192, 192, 192,
+ 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909,
+ 1910, 1911, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
+ 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
+ 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
+ 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
+ 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
+ 1912, 1912, 1912, 1913, 1914, 1913, 1914, 1914,
+ 1913, 1913, 1913, 1913, 1913, 1913, 1915, 1916,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924,
+ 1925, 1926, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1927, 1927, 1927, 1927, 1927, 1927, 1927, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
+ 1928, 1928, 1928, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1929, 1929, 1929, 1929, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1931, 1931, 1931, 1932, 1932, 1932, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1932, 1930, 1930, 1930, 1931, 1932,
+ 1931, 1932, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1931, 1932, 1932, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
+ 1930, 1930, 1930, 1930, 1930, 1930, 1930, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
+ 1933, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
+ 1934, 1934, 1934, 1934, 1934, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1934, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
+ 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
+ 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
+ 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
+ 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
+ 1935, 1935, 1935, 1935, 1935, 1935, 1935, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 1936,
+ 1936, 1936, 1936, 1937, 1937, 1937, 1937, 1937,
+ 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1938, 1939, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 192,
+ 192, 1277, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1941, 1941,
+ 1941, 1941, 1941, 1941, 1941, 1942, 1943, 1944,
+ 1944, 1944, 1940, 1940, 1940, 1945, 1942, 1942,
+ 1942, 1942, 1942, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1947, 1947, 1947, 1947, 1947,
+ 1947, 1947, 1947, 1940, 1940, 1948, 1948, 1948,
+ 1948, 1948, 1947, 1947, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1948, 1948, 1948, 1948, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1941, 1941, 1941, 1941, 1941,
+ 1941, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
+ 1940, 1940, 1940, 1940, 1940, 1940, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1756, 1756, 1949, 1949, 1949, 1756, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
+ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950,
+ 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950,
+ 1950, 1950, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 192, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1951, 192, 1951, 1951,
+ 192, 192, 1951, 192, 192, 1951, 1951, 192,
+ 192, 1951, 1951, 1951, 1951, 192, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
+ 1952, 1952, 192, 1952, 192, 1952, 1952, 1952,
+ 1952, 1953, 1952, 1952, 192, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+
+ 1952, 1952, 1952, 1952, 1951, 1951, 192, 1951,
+ 1951, 1951, 1951, 192, 192, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 192, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 192, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1951, 1951, 192, 1951, 1951, 1951, 1951, 192,
+ 1951, 1951, 1951, 1951, 1951, 192, 1951, 192,
+ 192, 192, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 192, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1269, 1269, 192, 192,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1954, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1955, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1954, 1952, 1952, 1952, 1952,
+
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1955, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1954, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1955,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1954,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1955, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
+ 1951, 1954, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1952, 1955, 1952, 1952, 1952, 1952,
+ 1952, 1952, 1956, 1957, 192, 192, 1958, 1959,
+ 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967,
+ 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965,
+ 1966, 1967, 1958, 1959, 1960, 1961, 1962, 1963,
+ 1964, 1965, 1966, 1967, 1958, 1959, 1960, 1961,
+ 1962, 1963, 1964, 1965, 1966, 1967, 1958, 1959,
+ 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967,
+
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286,
+
+ 1968, 1968, 1968, 1968, 318, 1968, 1968, 1968,
+ 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
+ 318, 1968, 1968, 318, 1968, 318, 318, 1968,
+ 318, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 318, 1968, 1968, 1968, 1968,
+ 318, 1968, 318, 1968, 318, 318, 318, 318,
+ 318, 318, 1968, 318, 318, 318, 318, 1968,
+ 318, 1968, 318, 1968, 318, 1968, 1968, 1968,
+ 318, 1968, 1968, 318, 1968, 318, 318, 1968,
+ 318, 1968, 318, 1968, 318, 1968, 318, 1968,
+ 318, 1968, 1968, 318, 1968, 318, 318, 1968,
+ 1968, 1968, 1968, 318, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 318, 1968, 1968, 1968, 1968,
+ 318, 1968, 1968, 1968, 1968, 318, 1968, 318,
+ 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 318, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 1968, 318, 318, 318, 318,
+ 318, 1968, 1968, 1968, 318, 1968, 1968, 1968,
+ 1968, 1968, 318, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
+ 1968, 1968, 1968, 1968, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+ 1969, 1969, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318,
+
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 192, 192, 192, 192,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 192,
+ 192, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 192,
+ 192, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 192, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1970, 1970, 1971, 1972, 1973, 1974, 1975, 1976,
+ 1977, 1978, 1979, 192, 192, 192, 192, 192,
+ 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
+ 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
+ 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
+ 1980, 1980, 1980, 1980, 1980, 1980, 1980, 192,
+ 1981, 1980, 1981, 1981, 1981, 1981, 1981, 1981,
+ 1981, 1981, 1981, 1981, 1981, 1980, 1981, 1980,
+ 1981, 1981, 1980, 1981, 1981, 1981, 1980, 1981,
+ 1981, 1981, 1980, 1980, 1980, 1980, 1980, 1981,
+ 1982, 1982, 1982, 1982, 1982, 1982, 1982, 740,
+ 1982, 1982, 1982, 1982, 1982, 1982, 1982, 740,
+ 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
+ 1982, 1982, 1983, 1983, 192, 192, 192, 192,
+ 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
+ 1982, 740, 1982, 740, 740, 1982, 1982, 740,
+ 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
+ 1982, 1982, 740, 740, 740, 740, 1982, 1982,
+ 1980, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
+ 1982, 1982, 1982, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 1984, 1984,
+ 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984,
+ 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984,
+ 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984,
+
+ 1985, 1986, 1986, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
+ 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
+ 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
+ 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
+ 1486, 1486, 1986, 1986, 1986, 1986, 1986, 1986,
+ 1986, 1986, 1986, 192, 192, 192, 192, 192,
+ 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
+ 1486, 192, 192, 192, 192, 192, 192, 192,
+ 1986, 1986, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1313, 1313, 1313, 1313, 1313, 1313, 192, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 192, 192, 192,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1312, 1312, 1313,
+ 1313, 1313, 1313, 1313, 1312, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 192, 1313, 1313,
+ 1313, 1313, 1313, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 192,
+ 1313, 192, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1312, 1313, 1312, 1313, 1312, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1312,
+ 1313, 1312, 1312, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 192, 1313, 1313, 1313, 1313, 192, 192, 192,
+
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 192, 192,
+ 1987, 1987, 1987, 1987, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 1313, 1313, 1313, 1313, 1313,
+
+ 1988, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1988, 1313, 1313, 1313, 1988, 1313, 1988,
+ 1313, 1988, 1313, 1988, 1313, 1313, 1313, 1988,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1988, 1988,
+ 1313, 1313, 1313, 1313, 1988, 1313, 1988, 1988,
+ 1313, 1313, 1313, 1313, 1988, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 192, 192, 192, 192, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1313, 1313, 1313, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
+ 1312, 1312, 1312, 1312, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 1989, 1989,
+
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
+ 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
+ 1991, 1991, 1991, 1991, 1991, 1991, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
+ 1992, 1992, 1992, 1992, 1992, 1992, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1989, 1989,
+
+ 1224, 1946, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1822, 1822, 1822, 1822, 288, 1822, 1822, 1822,
- 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822,
- 288, 1822, 1822, 288, 1822, 288, 288, 1822,
- 288, 1822, 1822, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 288, 1822, 1822, 1822, 1822,
- 288, 1822, 288, 1822, 288, 288, 288, 288,
- 288, 288, 1822, 288, 288, 288, 288, 1822,
- 288, 1822, 288, 1822, 288, 1822, 1822, 1822,
- 288, 1822, 1822, 288, 1822, 288, 288, 1822,
- 288, 1822, 288, 1822, 288, 1822, 288, 1822,
- 288, 1822, 1822, 288, 1822, 288, 288, 1822,
- 1822, 1822, 1822, 288, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 288, 1822, 1822, 1822, 1822,
- 288, 1822, 1822, 1822, 1822, 288, 1822, 288,
- 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 288, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 1822, 288, 288, 288, 288,
- 288, 1822, 1822, 1822, 288, 1822, 1822, 1822,
- 1822, 1822, 288, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822,
- 1822, 1822, 1822, 1822, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
- 1823, 1823, 288, 288, 288, 288, 288, 288,
- 288, 288, 288, 288, 288, 288, 288, 288,
-
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 177, 177, 177, 177,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
- 1242, 1242, 1242, 1242, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 177,
- 177, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 177,
- 177, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 177, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1824, 1824, 1825, 1826, 1827, 1828, 1829, 1830,
- 1831, 1832, 1833, 177, 177, 177, 177, 177,
- 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, 685, 685, 685, 685, 685, 177,
- 1834, 685, 1834, 1834, 1834, 1834, 1834, 1834,
- 1834, 1834, 1834, 1834, 1834, 685, 1834, 685,
- 1834, 1834, 685, 1834, 1834, 1834, 685, 1834,
- 1834, 1834, 685, 685, 685, 685, 685, 1834,
- 1834, 1834, 1834, 1834, 1834, 1834, 1834, 685,
- 1834, 1834, 1834, 1834, 1834, 1834, 1834, 685,
- 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
- 1834, 1834, 1835, 1835, 177, 177, 177, 177,
- 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
- 1834, 685, 1834, 685, 685, 1834, 1834, 685,
- 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
- 1834, 1834, 685, 685, 685, 685, 1834, 1834,
- 685, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
- 1834, 1834, 1834, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 1836, 1836,
- 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836,
- 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836,
- 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836,
-
- 1837, 1838, 1838, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366,
- 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366,
- 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366,
- 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366,
- 1366, 1366, 1838, 1838, 1838, 1838, 1838, 1838,
- 1838, 1838, 1838, 177, 177, 177, 177, 177,
- 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366,
- 1366, 177, 177, 177, 177, 177, 177, 177,
- 1838, 1838, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1212, 1212, 1212, 1212, 1212, 1212, 177, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 177, 177, 177,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1211, 1211, 1212,
- 1212, 1212, 1212, 1212, 1211, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 177, 1212, 1212,
- 1212, 1212, 1212, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 177,
- 1212, 177, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1211, 1212, 1211, 1212, 1211, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1211,
- 1212, 1211, 1211, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 177, 1212, 1212, 1212, 1212, 177, 177, 177,
-
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 177, 177,
- 1835, 1835, 1835, 1835, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 1212, 1212, 1212, 1212, 1212,
-
- 1839, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1839, 1212, 1212, 1212, 1839, 1212, 1839,
- 1212, 1839, 1212, 1839, 1212, 1212, 1212, 1839,
- 1212, 1212, 1212, 1212, 1212, 1212, 1839, 1839,
- 1212, 1212, 1212, 1212, 1839, 1212, 1839, 1839,
- 1212, 1212, 1212, 1212, 1839, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 177, 177, 177, 177, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
- 1212, 1212, 1212, 1212, 1212, 1212, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
- 1211, 1211, 1211, 1211, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
-
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 1840, 1840,
-
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
-
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
-
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1376, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
-
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842,
- 1842, 1842, 1842, 1842, 1842, 1842, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841,
- 1841, 1841, 1841, 1841, 1841, 1841, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
-
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372,
- 1372, 1372, 1372, 1372, 1372, 1372, 1840, 1840,
-
- 1138, 1800, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
-
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
-
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
-
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
-
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
- 1844, 1844, 1844, 1844, 1844, 1844, 1840, 1840,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
+ 1994, 1994, 1994, 1994, 1994, 1994, 1989, 1989,
};
#define GET_PROP_INDEX(ucs4) \
@@ -4835,1851 +4903,2001 @@ static const unsigned short uc_property_trie[] = {
(uc_property_trie[uc_property_trie[ucs2>>5] + (ucs2 & 0x1f)])
static const Properties uc_properties[] = {
- { 9, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 21, 2 },
- { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 5, 17, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 34, 2 },
- { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 5, 35, 2 },
- { 9, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 5, 35, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 33, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 21, 2 },
- { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 21, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 32, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 6, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 9, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 13, 3, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 2, 2 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 9, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 11, 8, 2 },
- { 20, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 16, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 10, 8, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 0, 8, 2 },
- { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 21, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 0, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 9, 2 },
- { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 2, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 12, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 2 },
- { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 1, 2 },
- { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 35, 2 },
- { 6, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 4, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 23, 10, 0, 0, -1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 17, 2 },
- { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 2 },
- { 26, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 9, 2 },
- { 5, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 18, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 743, 743, 775, 0, 0, 0, 0, 1, 0, 7, 6, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 0, 12, 2 },
- { 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 24, 10, 0, 0, -1, -16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 16, 13, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 19, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -232, -232, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 98, 98, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -121, 0, 0, -121, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -300, -300, -268, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 195, 195, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 210, 0, 0, 210, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 206, 0, 0, 206, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 205, 0, 0, 205, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 79, 0, 0, 79, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 202, 0, 0, 202, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 203, 0, 0, 203, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 207, 0, 0, 207, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 97, 97, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 211, 0, 0, 211, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 209, 0, 0, 209, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 213, 0, 0, 213, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 214, 0, 0, 214, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 218, 0, 0, 218, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 217, 0, 0, 217, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 219, 0, 0, 219, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 56, 56, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 2, 0, 1, 2, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 16, 0, 0, 0, -1, 0, 1, -1, 0, 1, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -2, -1, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -79, -79, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 109, 109, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -97, 0, 0, -97, 0, 0, 0, 0, 4, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -56, 0, 0, -56, 0, 0, 0, 0, 4, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 6, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 10795, 0, 0, 10795, 0, 0, 0, 0, 8, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -163, 0, 0, -163, 0, 0, 0, 0, 8, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 10792, 0, 0, 10792, 0, 0, 0, 0, 8, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10815, 10815, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -195, 0, 0, -195, 0, 0, 0, 0, 9, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 69, 0, 0, 69, 0, 0, 0, 0, 9, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 71, 0, 0, 71, 0, 0, 0, 0, 9, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10783, 10783, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10780, 10780, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10782, 10782, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -210, -210, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -206, -206, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -205, -205, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -202, -202, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -203, -203, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -207, -207, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 3, 3, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -209, -209, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -211, -211, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10743, 10743, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10749, 10749, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -213, -213, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -214, -214, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10727, 10727, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -218, -218, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -69, -69, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -217, -217, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -71, -71, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -219, -219, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 18, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 18, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 36 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 2 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 232, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 240, 0, -1, 0, 0, 84, 84, 116, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 1 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 4, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 1 },
- { 0, 17, 232, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 4, 1 },
- { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 4, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 4, 1 },
- { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 4, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 1 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 7, 6, 12, 4 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 4 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 38, 0, 0, 38, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 37, 0, 0, 37, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 64, 0, 0, 64, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 63, 0, 0, 63, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 101, 101, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -38, -38, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -37, -37, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 105, 105, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -31, -31, 1, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -64, -64, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -63, -63, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 8, 0, 0, 8, 0, 0, 0, 0, 10, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -62, -62, -30, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -57, -57, -25, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -47, -47, -15, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -54, -54, -22, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -8, -8, 0, 0, 0, 0, 0, 4, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -86, -86, -54, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -80, -80, -48, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -60, 0, 0, -60, 0, 0, 0, 0, 5, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -96, -96, -64, 0, 0, 0, 0, 5, 0, 7, 6, 12, 4 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 7, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 7, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 8, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 4, 0, 7, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 1, 0, 7, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 4, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 5 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 5 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 5 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 5 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 15, 0, 0, 15, 0, 0, 0, 0, 1, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -15, -15, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 1, 0, 7, 7, 12, 6 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 65, 62, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 12, 8, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 17, 6 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 9, 6 },
- { 13, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 7 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 7 },
- { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 7 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 7 },
- { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 7 },
- { 0, 17, 10, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 11, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 12, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 13, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 14, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 15, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 16, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 17, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 18, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 19, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 19, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 7 },
- { 0, 17, 20, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 21, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 22, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 20, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 7 },
- { 0, 17, 23, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 7 },
- { 0, 17, 24, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 0, 17, 25, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6, 7 },
- { 0, 17, 18, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 7 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 13, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 0, 12, 7 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 4, 4, 12, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 4, 4, 12, 8 },
- { 13, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 8 },
- { 26, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 8 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 8 },
- { 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 10, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 10, 11, 8, 8 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 8 },
- { 0, 17, 30, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 8 },
- { 0, 17, 31, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 8 },
- { 0, 17, 32, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 2 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 6, 2 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 8 },
- { 17, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 2 },
- { 0, 17, 27, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 28, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 29, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 30, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 31, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 32, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 33, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 34, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 8 },
- { 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 8 },
- { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 9, 11, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 8 },
- { 0, 17, 35, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 6, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 8 },
- { 17, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 8 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 8 },
- { 29, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 12, 12, 9 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 9 },
- { 10, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 4, 4, 12, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 9 },
- { 0, 17, 36, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 9 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 9 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 9 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 9 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 9 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 10 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 10 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 10 },
- { 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 66 },
- { 18, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 66 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 66 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 66 },
- { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 66 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 66 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 66 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 10, 11, 8, 66 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 12, 6, 66 },
- { 17, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 66 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 82 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 82 },
- { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 82 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 82 },
- { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 95 },
- { 18, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 95 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 95 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 95 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 95 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 8 },
- { 0, 17, 27, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 8 },
- { 0, 17, 28, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 8 },
- { 0, 17, 29, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 8 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 11 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 11 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 11 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 11 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 4, 4, 21, 11 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 11 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 11 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 4, 21, 11 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 17, 2 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 11 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 11 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 12 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 12 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 12 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 12 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 12 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 12 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 12 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 12 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 12 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 12 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 9, 12 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 13 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 13 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 4, 4, 21, 13 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 13 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 13 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 13 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 13 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 13 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 13 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 14 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 14 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 14 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 14 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 14 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 14 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 14 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 14 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 14 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 9, 14 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 15 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 15 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 15 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 15 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 15 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 15 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 15 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 15 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 15 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 16 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 16 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 16 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 16 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 16 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 16 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 16 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 9, 16 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 17 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 17 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 17 },
- { 0, 17, 84, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 17 },
- { 0, 17, 91, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 17 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 17 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 17 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 18 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 18 },
- { 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 18 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 18 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 18 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 18 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 18 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 18 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 4, 4, 21, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 19 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 19 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 19 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 19 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 19 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 19 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 19 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 19 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 4, 4, 21, 20 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 20 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 20 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 20 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 20 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 20 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 30, 21 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 30, 21 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 0, 8, 30, 21 },
- { 0, 17, 103, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 30, 21 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 30, 21 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 30, 21 },
- { 0, 17, 107, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 30, 21 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 21 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 21 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 21 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 30, 22 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 30, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 0, 8, 30, 22 },
- { 0, 17, 118, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 30, 22 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 30, 22 },
- { 0, 17, 122, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 30, 22 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 9, 11, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 30, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 7, 8, 12, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 12, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 12, 23 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 11, 9, 11, 23 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 12, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 23 },
- { 0, 17, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 13, 0, 23 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 13, 1, 23 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 7, 4, 4, 21, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 23 },
- { 0, 17, 129, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 0, 17, 130, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 0, 17, 132, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 7, 4, 4, 17, 23 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 21, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 17, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 23 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 17, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 18, 23 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 23 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 4, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 30, 24 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 30, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 30, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 30, 24 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 30, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 4, 4, 30, 24 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 30, 24 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 30, 24 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 30, 24 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 30, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 30, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 24 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 12, 17, 24 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 24 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 30, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 24 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 30, 24 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 30, 24 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 30, 24 },
- { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 1, 0, 7, 7, 12, 25 },
- { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 13, 0, 7, 7, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 25 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 7, 8, 25, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 8, 7, 8, 25, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 7, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 7, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 7, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 10, 7, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 27 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 27 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 27 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 17, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 12, 12, 27 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 27 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 27 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 28 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 17, 29 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 29 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 29 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 12, 12, 29 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 29 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 17, 30 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 30 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 13, 0, 30 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 13, 1, 30 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 31 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 17, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 31 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 42 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 42 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 42 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 43 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 43 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 43 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 12, 17, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 44 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 44 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 45 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 45 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 30, 32 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 30, 32 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 4, 4, 30, 32 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 30, 32 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 17, 32 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 32 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 30, 32 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 32 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 9, 32 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 30, 32 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 32 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 32 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 6, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 12, 6, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 17, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 18, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 6, 33 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 12, 6, 33 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 33 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 4, 33 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 11, 9, 11, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 33 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 12, 33 },
- { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 47 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 47 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 4, 4, 21, 47 },
- { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 47 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 47 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 47 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 47 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 12, 6, 47 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 47 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 30, 48 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 30, 56 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 30, 56 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 30, 56 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 4, 4, 30, 56 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 11, 9, 11, 56 },
- { 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 30, 56 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 30, 56 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 32 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 55 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 55 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 55 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 4, 4, 21, 55 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 55 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 30, 78 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 4, 30, 78 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 30, 78 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 30, 78 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 30, 78 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 30, 78 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 78 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 78 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 30, 78 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 30, 78 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 30, 78 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 62 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 4, 4, 21, 62 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 62 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 62 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 4, 4, 21, 62 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 11, 9, 11, 62 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 12, 17, 62 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 62 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 17, 62 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 62 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 62 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 62 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 67 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 21, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 67 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 21, 67 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 67 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 67 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 93 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 93 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 4, 4, 21, 93 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 93 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 4, 4, 21, 93 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 93 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 68 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 21, 68 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 68 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 68 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 17, 68 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 17, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 69 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 69 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 69 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 17, 69 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 67 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 1 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 1 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 4, 21, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 2 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 2 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 1 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 5 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 4 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 5, 5, 0, 0, 1, 1, 0, 8, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 3814, 3814, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 4 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 1 },
- { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 1 },
- { 0, 17, 214, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 1 },
- { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 115, 115, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 118, 118, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 124, 124, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -59, -59, -58, 0, 0, 0, 0, 2, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -7615, 0, 0, -7615, 0, 0, 0, 0, 10, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 8, 8, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -8, 0, 0, -8, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 127, 127, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 134, 134, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 138, 138, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 74, 74, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 86, 86, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 100, 100, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 128, 128, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 126, 126, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 176, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 179, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 182, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 185, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 188, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 191, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 194, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 197, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 176, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 179, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 182, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 185, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 188, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 191, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 194, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 197, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 200, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 203, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 206, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 209, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 212, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 215, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 218, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 221, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 200, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 203, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 206, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 209, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 212, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 215, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 218, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 221, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 224, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 227, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 230, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 233, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 236, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 239, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 242, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 245, 8, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 224, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 227, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 230, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 233, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 236, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 239, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 242, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 245, 0, -8, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 260, 257, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 248, 9, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 266, 263, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 142, 142, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 297, 293, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -74, 0, 0, -74, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -9, 248, 0, -9, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -7205, -7205, -7173, 0, 0, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 272, 269, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 251, 9, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 278, 275, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 145, 145, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 305, 301, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -86, 0, 0, -86, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -9, 251, 0, -9, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 148, 148, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 152, 152, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 155, 155, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -100, 0, 0, -100, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 159, 159, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 166, 166, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 169, 169, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -112, 0, 0, -112, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 284, 281, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 254, 9, 0, 0, 1, 0, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 290, 287, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 173, 173, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 313, 309, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -128, 0, 0, -128, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -126, 0, 0, -126, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -9, 254, 0, -9, 0, 1, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 18, 4 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 17, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 4, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 4, 20, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 10, 18, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 10, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 10, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 19, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 13, 3, 2 },
- { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 13, 3, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 0, 2 },
- { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 10, 15, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 0, 17, 2 },
- { 7, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 35, 2 },
- { 8, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 35, 2 },
- { 10, 11, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 10, 14, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 10, 16, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 10, 12, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 10, 15, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 6, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 4, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 2 },
- { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 5, 2 },
- { 26, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 0, 8, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 12, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 12, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 12, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 17, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 5, 17, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 4, 4, 22, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 4, 4, 12, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 4, 4, 12, 2 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 12, 0 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 21, 2 },
- { 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 6, 12, 3 },
- { 5, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 6, 12, 3 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 9, 2 },
- { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 9, 2 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 21, 1 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 1 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 7, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 9, 2 },
- { 14, 0, 0, 0, -1, 0, -7517, 0, 0, -7517, 0, 0, 0, 0, 1, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -8383, 0, 0, -8383, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -8262, 0, 0, -8262, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 28, 0, 0, 28, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 6, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 6, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 7, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, -28, -28, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 3 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 4, 0, 0, 0, -1, 0, 16, 0, 0, 16, 0, 0, 0, 0, 1, 0, 7, 7, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, -16, -16, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 3 },
- { 26, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2016, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 138, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1824, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2104, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2108, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2106, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -138, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 14, 2 },
- { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 26, 0, 0, 26, 0, 0, 0, 0, 1, 0, 7, 7, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, -26, -26, 0, 0, 0, 0, 0, 1, 0, 7, 6, 12, 2 },
- { 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 3, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 13, 1, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 13, 1, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 13, 1, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 54 },
- { 21, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 13, 1, 2 },
- { 21, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 13, 1, 2 },
- { 26, 10, 0, 0, -1, -1824, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2016, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2104, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2106, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, -2108, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 8, 0, 7, 7, 12, 57 },
- { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 57 },
- { 14, 0, 0, 0, -1, 0, -10743, 0, 0, -10743, 0, 0, 0, 0, 9, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -3814, 0, 0, -3814, 0, 0, 0, 0, 9, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10727, 0, 0, -10727, 0, 0, 0, 0, 9, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -10795, -10795, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -10792, -10792, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10780, 0, 0, -10780, 0, 0, 0, 0, 10, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10749, 0, 0, -10749, 0, 0, 0, 0, 10, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10783, 0, 0, -10783, 0, 0, 0, 0, 10, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10782, 0, 0, -10782, 0, 0, 0, 0, 11, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10815, 0, 0, -10815, 0, 0, 0, 0, 11, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 46 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 46 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 7, 6, 12, 46 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 46 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 7, 6, 12, 46 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6, 46 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 17, 46 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 8, 0, 7, 6, 12, 25 },
- { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 13, 0, 7, 6, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 58 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 58 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 58 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 17, 58 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 58 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 13, 3, 2 },
- { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 13, 3, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 2 },
- { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 13, 3, 2 },
- { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 13, 3, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 6, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 17, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 19, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 14, 37 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 14, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 14, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 5, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 14, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 14, 37 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 2 },
- { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 1, 2 },
- { 0, 17, 218, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 1, 0, 224, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 26 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 8, 14, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 14, 37 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 5, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 5, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 14, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 5, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 14, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 5, 34 },
- { 0, 17, 8, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 1 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 5, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 5, 34 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 14, 34 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 0, 5, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 8, 5, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 8, 14, 35 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 8, 5, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 8, 5, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 8, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 14, 26 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 8, 5, 35 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 26 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 14, 26 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 14, 2 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 14, 26 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 14, 37 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 14, 38 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 5, 38 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 14, 38 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 14, 38 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 83 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 83 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 17, 83 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 17, 83 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 70 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 70 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 17, 70 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 6, 70 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 17, 70 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 70 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 5 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 5 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 5 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 5 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 5 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 84 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 84 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 84 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 84 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 17, 84 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 17, 84 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 2 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 7, 0, 0, 7, 1, 0, 0, 1, 10, 0, 7, 7, 12, 3 },
- { 28, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 9, 0, 0, 9, 1, 0, 0, 1, 12, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 11, 0, 0, 11, 1, 0, 0, 1, 13, 0, 7, 7, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 6, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 59 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 59 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 59 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 4, 4, 21, 59 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 59 },
- { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 65 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 18, 65 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 12, 6, 65 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 21, 71 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 71 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 71 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 17, 71 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 71 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 11 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 11 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 72 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 72 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 72 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 72 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 17, 72 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 17, 72 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 73 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 73 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 21, 73 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 21, 73 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 73 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 85 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 4, 21, 85 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 85 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 85 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 4, 21, 85 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 85 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 17, 85 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 17, 85 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 85 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 85 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 77 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 4, 4, 21, 77 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 4, 4, 21, 77 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 9, 11, 77 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 77 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 12, 17, 77 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 30, 24 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 30, 24 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 30, 24 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 30, 79 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 30, 79 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 30, 79 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 30, 79 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 30, 79 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 86 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 86 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 86 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 12, 17, 86 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 86 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 86 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 27 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 86 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 4, 21, 86 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 86 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 17, 86 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 86 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 11, 9, 11, 86 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 11, 7, 8, 23, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 12, 7, 8, 24, 26 },
- { 11, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 31, 0 },
- { 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 14, 37 },
- { 15, 0, 0, 0, -1, 0, 0, 25, 22, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 31, 28, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 37, 34, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 44, 40, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 52, 48, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 59, 56, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 71, 68, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 77, 74, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 83, 80, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 89, 86, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 95, 92, 0, 0, 1, 1, 0, 1, 0, 7, 6, 12, 6 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 8, 13, 7 },
- { 0, 17, 26, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 21, 7 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 7 },
- { 28, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 8 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 0 },
- { 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 8 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, 4, 21, 1 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 10, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 9, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 10, 0, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 13, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 2 },
- { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 14, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 12, 0, 14, 2 },
- { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 13, 0, 2 },
- { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 13, 1, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 11, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 14, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 10, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 0, 5, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 11, 5, 2 },
- { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 20, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 14, 2 },
- { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, 8, 12, 8 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 4, 22, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 0, 14, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 7, 7, 14, 3 },
- { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 14, 2 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 7, 6, 14, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 8, 12, 35 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 5, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 8, 12, 26 },
- { 10, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 4, 4, 21, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 29, 2 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 49 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 17, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 17, 2 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 2 },
- { 4, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 4 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 4 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 4 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 74 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 75 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 8, 12, 39 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 39 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 8, 12, 40 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 8, 12, 40 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 50 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 17, 50 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 60 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 17, 60 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 60 },
- { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 5, 0, 7, 7, 12, 41 },
- { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 7, 0, 7, 7, 12, 41 },
- { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 5, 0, 7, 6, 12, 41 },
- { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 41 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 51 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 52 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 11, 9, 11, 52 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 8, 12, 53 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 87 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 17, 87 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 87 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 64 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 64 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 64 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 17, 64 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 8, 12, 76 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 76 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 98 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 97 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 8, 12, 61 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 61 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 61 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 61 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 61 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 61 },
- { 5, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 61 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 61 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 17, 61 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 12, 17, 61 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 61 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 88 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 88 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 88 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 80 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 17, 80 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 89 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 89 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 90 },
- { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 90 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 91 },
- { 5, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 5, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 8 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 4, 4, 21, 94 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 94 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 94 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 4, 4, 21, 94 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 12, 17, 94 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 94 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 11, 9, 11, 94 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 92 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 4, 21, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 92 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 92 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 4, 4, 21, 92 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 92 },
- { 10, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 4, 4, 12, 92 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 17, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 101 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 101 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 96 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 96 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 96 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 96 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 96 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 96 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 17, 96 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 12, 17, 96 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 100 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 100 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 12, 17, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 100 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 17, 100 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 102 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 102 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 102 },
- { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 102 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 102 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 11, 9, 11, 102 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 63 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 8, 12, 63 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 17, 63 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 12, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 0, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 8, 1, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 8, 12, 84 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 99 },
- { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 7, 4, 4, 21, 99 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 4, 21, 99 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 99 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 6, 8, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 14, 34 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 2 },
- { 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 4, 4, 21, 2 },
- { 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 4, 4, 21, 2 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 4, 4, 21, 1 },
- { 1, 0, 226, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 4, 4, 21, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 4, 4, 21, 2 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 4, 21, 4 },
- { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 7, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 6, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 6, 12, 2 },
- { 26, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 2 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 7, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 6, 12, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 11, 9, 11, 2 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 8, 12, 8 },
- { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 8 },
- { 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 5, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 5, 5, 0, 28, 2 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 14, 34 },
- { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 14, 2 },
- { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 14, 2 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 12, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 14, 37 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 4, 4, 21, 1 },
- { 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 12, 0 }
+ { 9, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 21, 2 },
+ { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 5, 17, 2 },
+ { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 34, 2 },
+ { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 5, 35, 2 },
+ { 9, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 5, 35, 2 },
+ { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 33, 2 },
+ { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 21, 2 },
+ { 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 21, 2 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 32, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
+ { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 13, 3, 2 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 2, 2 },
+ { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 11, 8, 2 },
+ { 20, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 16, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 10, 8, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 7, 2 },
+ { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 0, 8, 2 },
+ { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 21, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
+ { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 2, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 2 },
+ { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
+ { 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 35, 2 },
+ { 6, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 4, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 23, 10, 0, 0, -1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 17, 2 },
+ { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
+ { 26, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
+ { 5, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 18, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 743, 743, 775, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 0, 12, 2 },
+ { 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 24, 10, 0, 0, -1, -16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 16, 13, 0, 0, 1, 1, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 19, 0, 0, 0, 1, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -232, -232, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 98, 98, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -121, 0, 0, -121, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -300, -300, -268, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 195, 195, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 210, 0, 0, 210, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 206, 0, 0, 206, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 205, 0, 0, 205, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 79, 0, 0, 79, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 202, 0, 0, 202, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 203, 0, 0, 203, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 207, 0, 0, 207, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 97, 97, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 211, 0, 0, 211, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 209, 0, 0, 209, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 213, 0, 0, 213, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 214, 0, 0, 214, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 218, 0, 0, 218, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 217, 0, 0, 217, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 219, 0, 0, 219, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 56, 56, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 2, 0, 1, 2, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
+ { 16, 0, 0, 0, -1, 0, 1, -1, 0, 1, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -2, -1, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -79, -79, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 109, 109, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -97, 0, 0, -97, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -56, 0, 0, -56, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 17, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 17, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 6, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 10795, 0, 0, 10795, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -163, 0, 0, -163, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 10792, 0, 0, 10792, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10815, 10815, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -195, 0, 0, -195, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 69, 0, 0, 69, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 71, 0, 0, 71, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10783, 10783, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10780, 10780, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10782, 10782, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -210, -210, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -206, -206, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -205, -205, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -202, -202, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -203, -203, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -207, -207, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 3, 3, 0, 0, 1, 1, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -209, -209, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -211, -211, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10743, 10743, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10749, 10749, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -213, -213, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -214, -214, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10727, 10727, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -218, -218, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -69, -69, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -217, -217, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -71, -71, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -219, -219, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 2 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 18, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 36 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 232, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 4, 4, 4, 21, 1 },
+ { 0, 17, 240, 0, -1, 0, 0, 84, 84, 116, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 232, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 4 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 4 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 4 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 10, 0, 8, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 4 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 38, 0, 0, 38, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 9, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 37, 0, 0, 37, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 64, 0, 0, 64, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 63, 0, 0, 63, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 101, 101, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -38, -38, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -37, -37, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 105, 105, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -31, -31, 1, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -64, -64, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -63, -63, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, 0, 8, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -62, -62, -30, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -57, -57, -25, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -47, -47, -15, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -54, -54, -22, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -8, -8, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -86, -86, -54, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, -48, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -60, 0, 0, -60, 0, 0, 0, 0, 5, 80, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -96, -96, -64, 0, 0, 0, 0, 5, 80, 0, 7, 6, 12, 4 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 7, 0, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 7, 80, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 4, 17, 0, 7, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 4, 17, 0, 7, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 5 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 5 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 5 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
+ { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 15, 0, 0, 15, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -15, -15, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 17, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 17, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 0, 7, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 6 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 6 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 6 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 12, 6 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 65, 62, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 12, 8, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 6 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 9, 6 },
+ { 13, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 10, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 11, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 12, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 13, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 14, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 15, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 16, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 17, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 18, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 19, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 19, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 20, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 21, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 22, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 20, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 7 },
+ { 0, 17, 23, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 7 },
+ { 0, 17, 24, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 25, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 7 },
+ { 0, 17, 18, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 13, 7 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 7 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 0, 12, 7 },
+ { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 4, 4, 12, 8 },
+ { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 3, 4, 4, 12, 8 },
+ { 13, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
+ { 26, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
+ { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 8 },
+ { 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10, 8 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 11, 8, 8 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 8 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 30, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 31, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 32, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 2 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 8 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 2 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 8 },
+ { 17, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 2 },
+ { 0, 17, 27, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 28, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 29, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 30, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 31, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 32, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 33, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 34, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 8 },
+ { 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 8 },
+ { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 9, 11, 8 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 8 },
+ { 0, 17, 35, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 8 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 8 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
+ { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
+ { 17, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 8 },
+ { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 29, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 8 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 8 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 9 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 9 },
+ { 10, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 12, 9 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 9 },
+ { 0, 17, 36, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 9 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 9 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 9 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 10 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 10 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 10 },
+ { 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 3, 1, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
+ { 18, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 66 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
+ { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 66 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 66 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 66 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 11, 8, 66 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 6, 66 },
+ { 17, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 66 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 82 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 82 },
+ { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 82 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 82 },
+ { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 95 },
+ { 18, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 95 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 95 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 95 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 95 },
+ { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 8 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 27, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 28, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 29, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 11 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 11 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 11 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 11 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 11 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 11 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 17, 2 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 11 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 11 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 12 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 12 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 12 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 12 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 12 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 12 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 12 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 12 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 12 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 9, 12 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 13 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 4, 4, 21, 13 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 13 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 13 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 13 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 13 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 14 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 14 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 14 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 14 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 14 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 9, 14 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 15 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 15 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 15 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 15 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 15 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 15 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 15 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 15 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 15 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 15 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 16 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 16 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 16 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 16 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 16 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 16 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 16 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 9, 16 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 17 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 17 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 17 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 4, 4, 21, 17 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
+ { 0, 17, 84, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
+ { 0, 17, 91, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 17 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 17 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 17 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 17 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 18 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 18 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 18 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 18 },
+ { 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 18 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 18 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 18 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 18 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 19 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 19 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 19 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 19 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 19 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 19 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 19 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 19 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 19 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 4, 4, 21, 20 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 20 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 20 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 20 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 20 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 7, 4, 4, 21, 20 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 20 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 21 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 7, 0, 8, 30, 21 },
+ { 0, 17, 103, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 21 },
+ { 0, 17, 107, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 21 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 21 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 22 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 7, 0, 8, 30, 22 },
+ { 0, 17, 118, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 22 },
+ { 0, 17, 122, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 8, 30, 22 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 8, 30, 22 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 7, 8, 12, 23 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 80, 0, 0, 0, 4, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 23 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 23 },
+ { 0, 17, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 13, 0, 23 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 13, 1, 23 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 7, 4, 4, 21, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 0, 7, 8, 12, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 23 },
+ { 0, 17, 129, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 130, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 4, 4, 4, 21, 23 },
+ { 0, 17, 132, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 80, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 7, 4, 4, 17, 23 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 23 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 23 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 23 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 18, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 18, 23 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 23 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 4, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 24 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 30, 24 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 0, 0, 8, 30, 24 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 4, 4, 30, 24 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 4, 30, 24 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 30, 24 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 4, 4, 30, 24 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 30, 24 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 17, 24 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 24 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 4, 4, 30, 24 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 24 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 30, 24 },
+ { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 25 },
+ { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 13, 0, 0, 7, 7, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 25 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 7, 8, 25, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 7, 8, 25, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 7, 8, 26, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 9, 7, 8, 26, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 9, 7, 8, 26, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 10, 7, 8, 27, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 7, 8, 27, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 10, 7, 8, 27, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 27 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 27 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 27 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 27 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 27 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 27 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 27 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 27 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 28 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 29 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 29 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 29 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 29 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 29 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 17, 30 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 30 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 30 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 1, 30 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 31 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 2 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 31 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 42 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 43 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 17, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 44 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 44 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 45 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 45 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 32 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 32 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 4, 4, 30, 32 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 32 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 32 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 32 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 32 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 32 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 9, 32 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 30, 32 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 32 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 6, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 6, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 33 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 33 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 6, 33 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 6, 33 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 4, 33 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 33 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 33 },
+ { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 33 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 47 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 4, 4, 21, 47 },
+ { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 47 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 6, 47 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 8, 30, 48 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 30, 56 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 56 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 4, 4, 30, 56 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 4, 4, 30, 56 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 56 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 30, 56 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 32 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 55 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 4, 4, 21, 55 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 55 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 78 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 30, 78 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 4, 4, 30, 78 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 78 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 78 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 78 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 30, 78 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 4, 4, 21, 62 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 62 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 17, 0, 7, 8, 12, 62 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 204, 7, 4, 4, 21, 62 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 17, 7, 4, 4, 21, 62 },
+ { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 4, 4, 21, 62 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 17, 62 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 62 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 62 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 62 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 67 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 67 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 67 },
+ { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 67 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 67 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 67 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 67 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 93 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 93 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
+ { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 93 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 93 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 68 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 68 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 68 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 68 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 69 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 69 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 69 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 67 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
+ { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 2 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 2 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 1 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 5 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 7, 6, 12, 4 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, 5, 5, 0, 0, 1, 1, 0, 8, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 3814, 3814, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 4 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 214, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 1 },
+ { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 115, 115, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 118, 118, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 124, 124, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -59, -59, -58, 0, 0, 0, 0, 2, 81, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -7615, 0, 0, -7615, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 8, 8, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -8, 0, 0, -8, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 127, 127, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 134, 134, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 138, 138, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 74, 74, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 74, 74, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 86, 86, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 86, 86, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 100, 100, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 100, 100, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 128, 128, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 128, 128, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 126, 126, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 126, 126, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 176, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 179, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 182, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 185, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 188, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 191, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 194, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 197, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 176, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 179, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 182, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 185, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 188, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 191, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 194, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 197, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 200, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 203, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 206, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 209, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 212, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 215, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 218, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 221, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 200, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 203, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 206, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 209, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 212, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 215, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 218, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 221, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 224, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 227, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 230, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 233, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 236, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 239, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 242, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 245, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 224, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 227, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 230, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 233, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 236, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 239, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 242, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 245, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 260, 257, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 248, 9, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 266, 263, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 142, 142, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 297, 293, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -74, 0, 0, -74, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -74, 0, 0, -74, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -9, 248, 0, -9, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -7205, -7205, -7173, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 272, 269, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 251, 9, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 278, 275, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 145, 145, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 305, 301, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -86, 0, 0, -86, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -86, 0, 0, -86, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -9, 251, 0, -9, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 148, 148, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 101, 101, 0, 0, 1, 1, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 152, 152, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 155, 155, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -100, 0, 0, -100, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -100, 0, 0, -100, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 159, 159, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 105, 105, 0, 0, 1, 1, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 166, 166, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 169, 169, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -112, 0, 0, -112, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -112, 0, 0, -112, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 0, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 284, 281, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 254, 9, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 290, 287, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 173, 173, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 313, 309, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -128, 0, 0, -128, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -128, 0, 0, -128, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -126, 0, 0, -126, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -126, 0, 0, -126, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -9, 254, 0, -9, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 0, 18, 4 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 5, 17, 2 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 17, 2 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 4, 2 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 4, 20, 2 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 10, 18, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 10, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 4, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 17, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 19, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 13, 3, 2 },
+ { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 13, 3, 2 },
+ { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
+ { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 10, 15, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 15, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 0, 17, 2 },
+ { 7, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 35, 2 },
+ { 8, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 35, 2 },
+ { 10, 11, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 14, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 16, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 12, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 15, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 6, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 5, 4, 2 },
+ { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
+ { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 5, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 5, 2 },
+ { 26, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 0, 8, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 12, 5, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 12, 5, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
+ { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 12, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 12, 2 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 5, 17, 2 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 22, 2 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 12, 2 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 3, 4, 4, 12, 2 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 12, 0 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 7, 6, 12, 3 },
+ { 5, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 7, 6, 12, 3 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 10, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 9, 2 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 9, 2 },
+ { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
+ { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 9, 2 },
+ { 14, 0, 0, 0, -1, 0, -7517, 0, 0, -7517, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -8383, 0, 0, -8383, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -8262, 0, 0, -8262, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 3 },
+ { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 28, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 7, 6, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 7, 6, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 7, 7, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, -28, -28, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 4, 0, 0, 0, -1, 0, 16, 0, 0, 16, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
+ { 4, 0, 0, 0, -1, 0, 0, -16, -16, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 3 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 3 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 2016, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 138, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 1824, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 2104, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 2108, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 2106, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -138, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 13, 1, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 14, 2 },
+ { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 26, 0, 0, 26, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, -26, -26, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 2 },
+ { 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 14, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 14, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 14, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 14, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 2 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 1, 2 },
+ { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 1, 2 },
+ { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 1, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 54 },
+ { 21, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 1, 2 },
+ { 21, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 13, 1, 2 },
+ { 26, 10, 0, 0, -1, -1824, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -2016, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 85, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -2104, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -2106, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, -2108, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 57 },
+ { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 57 },
+ { 14, 0, 0, 0, -1, 0, -10743, 0, 0, -10743, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -3814, 0, 0, -3814, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10727, 0, 0, -10727, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -10795, -10795, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -10792, -10792, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10780, 0, 0, -10780, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10749, 0, 0, -10749, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10783, 0, 0, -10783, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10782, 0, 0, -10782, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 80, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10815, 0, 0, -10815, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 46 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 46 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 0, 7, 6, 12, 46 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 46 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 0, 7, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 0, 7, 6, 12, 46 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 46 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 46 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 25 },
+ { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 13, 0, 0, 7, 6, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 58 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 58 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 8, 12, 58 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 17, 58 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 58 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
+ { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
+ { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
+ { 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 3, 2 },
+ { 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 3, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 6, 2 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 19, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 37 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 0, 14, 37 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 2 },
+ { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 14, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 5, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 2 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 37 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 2 },
+ { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
+ { 0, 17, 218, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 1, 0, 224, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 26 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 14, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 8, 14, 37 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 5, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 5, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 14, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 5, 34 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 34 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 8, 14, 34 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 8, 5, 34 },
+ { 0, 17, 8, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 0, 5, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 5, 34 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 8, 5, 34 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 8, 14, 34 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 6, 0, 5, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 5, 35 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 14, 35 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 6, 8, 14, 35 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 5, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 5, 35 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 6, 8, 5, 35 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 6, 8, 14, 35 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 14, 26 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 6, 8, 5, 35 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 26 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 14, 26 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 14, 2 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 14, 2 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 14, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 14, 26 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 0, 14, 35 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 14, 37 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 14, 38 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 5, 38 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 38 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 14, 38 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 83 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 83 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 83 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 83 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 70 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 70 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 70 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 6, 70 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 70 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 5 },
+ { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 5 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 5 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 5 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 84 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 84 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 84 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 84 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 84 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 84 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 7, 0, 0, 7, 1, 0, 0, 1, 10, 0, 0, 7, 7, 12, 3 },
+ { 28, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, 0, 9, 1, 0, 0, 1, 12, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 0, 7, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 0, 7, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 11, 0, 0, 11, 1, 0, 0, 1, 13, 0, 0, 7, 7, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 7, 6, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 59 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 4, 4, 21, 59 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 59 },
+ { 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 65 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 18, 65 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 6, 65 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 71 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 71 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 71 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 71 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 11 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 72 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 72 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 72 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 73 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 73 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 73 },
+ { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 73 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 73 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 85 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 85 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
+ { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 85 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 85 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 85 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 85 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 85 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 77 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 77 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 77 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 77 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 77 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 24 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 24 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 24 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 79 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 79 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 79 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 79 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 79 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 86 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 86 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 86 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 86 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 27 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 86 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 86 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 86 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 11, 7, 8, 23, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 12, 7, 8, 24, 26 },
+ { 11, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 31, 0 },
+ { 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 0 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 85, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 85, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 85, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 85, 0, 0, 8, 14, 37 },
+ { 15, 0, 0, 0, -1, 0, 0, 25, 22, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 31, 28, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 37, 34, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 44, 40, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 52, 48, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 59, 56, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 71, 68, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 77, 74, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 83, 80, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 89, 86, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 95, 92, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 85, 0, 7, 8, 13, 7 },
+ { 0, 17, 26, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 13, 7 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 13, 7 },
+ { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 7 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 8 },
+ { 28, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 8 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 0 },
+ { 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 10, 8 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 11, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 11, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 9, 11, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 0, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 6, 2 },
+ { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 13, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 15, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
+ { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 12, 0, 14, 2 },
+ { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
+ { 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 13, 1, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 11, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 10, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 0, 5, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 9, 11, 5, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 6, 2 },
+ { 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 20, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
+ { 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 8 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 22, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 0, 14, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 80, 0, 7, 7, 14, 3 },
+ { 21, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 14, 3 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 13, 0, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 13, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 5, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 8, 12, 35 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 8, 5, 35 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 8, 5, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 4, 4, 4, 5, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 26 },
+ { 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
+ { 10, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 21, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 29, 2 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 0 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 49 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 2 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
+ { 4, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 4 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 4 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 4 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 74 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 75 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 7, 8, 12, 39 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 39 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 7, 8, 12, 40 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 7, 8, 12, 40 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 50 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 50 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 60 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 60 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 60 },
+ { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 5, 0, 0, 7, 7, 12, 41 },
+ { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 7, 0, 0, 7, 7, 12, 41 },
+ { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 5, 0, 0, 7, 6, 12, 41 },
+ { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 41 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 51 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 52 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 53 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 87 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 87 },
+ { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 87 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 64 },
+ { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 64 },
+ { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 64 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 64 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 76 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 76 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 98 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 97 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 61 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 5, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
+ { 5, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
+ { 5, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
+ { 5, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
+ { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 61 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 17, 61 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 88 },
+ { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 88 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 88 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 80 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 80 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 89 },
+ { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 89 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 90 },
+ { 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 90 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 91 },
+ { 5, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 5, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 94 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 94 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 17, 94 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 92 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 92 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 17, 0, 7, 8, 12, 92 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 204, 4, 4, 4, 21, 92 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 92 },
+ { 10, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 3, 4, 4, 12, 92 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 92 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 101 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 96 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 204, 4, 4, 4, 21, 96 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 96 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 17, 4, 4, 4, 21, 96 },
+ { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 96 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 96 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 100 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 100 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 100 },
+ { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 100 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 100 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 100 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 100 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 102 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 102 },
+ { 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 102 },
+ { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 63 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 63 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 63 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 81 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 0, 81 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 1, 81 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 84 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 99 },
+ { 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 99 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 99 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 99 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 6, 8, 14, 35 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 8, 14, 34 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 85, 0, 0, 0, 12, 2 },
+ { 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 2 },
+ { 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 4, 4, 21, 2 },
+ { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
+ { 1, 0, 226, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 4, 4, 21, 2 },
+ { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 3, 4, 4, 21, 2 },
+ { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 4 },
+ { 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 7, 7, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 7, 6, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 7, 6, 12, 2 },
+ { 26, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 0, 0, 12, 2 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 0, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 7, 7, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 7, 6, 12, 2 },
+ { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 7, 8, 12, 8 },
+ { 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 8 },
+ { 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 5, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 0, 0, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 5, 5, 0, 28, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 14, 34 },
+ { 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 0, 0, 14, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
+ { 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 14, 2 },
+ { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 8, 14, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 85, 0, 0, 8, 14, 37 },
+ { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
+ { 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0 }
};
static inline const Properties *qGetProp(uint ucs4)
diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h
index 8f0b7aabad..08b8d58e70 100644
--- a/src/corelib/tools/qunicodetables_p.h
+++ b/src/corelib/tools/qunicodetables_p.h
@@ -79,8 +79,9 @@ struct Properties {
ushort titleCaseSpecial : 1;
ushort caseFoldSpecial : 1;
ushort unicodeVersion : 4;
- ushort graphemeBreakClass : 8; /* 4 used */
- ushort wordBreakClass : 8; /* 4 used */
+ ushort nfQuickCheck : 8;
+ ushort graphemeBreakClass : 4; /* 4 used */
+ ushort wordBreakClass : 4; /* 4 used */
ushort sentenceBreakClass : 8; /* 4 used */
ushort lineBreakClass : 8; /* 6 used */
ushort script : 8; /* 7 used */
diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/tools/qunicodetools.cpp
index 4d5c978fd5..b3e55a5abc 100644
--- a/src/corelib/tools/qunicodetools.cpp
+++ b/src/corelib/tools/qunicodetools.cpp
@@ -603,28 +603,35 @@ Q_CORE_EXPORT void initCharAttributes(const ushort *string, int length,
if (options & WhiteSpaces)
getWhiteSpaces(string, length, attributes);
- if (!items || numItems <= 0)
- return;
if (!qt_initcharattributes_default_algorithm_only) {
+ if (!items || numItems <= 0)
+ return;
+
QVarLengthArray<HB_ScriptItem, 64> scriptItems;
scriptItems.reserve(numItems);
int start = 0;
+ HB_Script startScript = script_to_hbscript(items[start].script);
+ if (Q_UNLIKELY(startScript == HB_Script_Inherited))
+ startScript = HB_Script_Common;
for (int i = start + 1; i < numItems; ++i) {
- if (script_to_hbscript(items[i].script) == script_to_hbscript(items[start].script))
+ HB_Script script = script_to_hbscript(items[i].script);
+ if (Q_LIKELY(script == startScript || script == HB_Script_Inherited))
continue;
+ Q_ASSERT(items[i].position > items[start].position);
HB_ScriptItem item;
item.pos = items[start].position;
item.length = items[i].position - items[start].position;
- item.script = script_to_hbscript(items[start].script);
+ item.script = startScript;
item.bidiLevel = 0; // unused
scriptItems.append(item);
start = i;
+ startScript = script;
}
if (items[start].position + 1 < length) {
HB_ScriptItem item;
item.pos = items[start].position;
item.length = length - items[start].position;
- item.script = script_to_hbscript(items[start].script);
+ item.script = startScript;
item.bidiLevel = 0; // unused
scriptItems.append(item);
}
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 825e05ae1b..34a64dafe2 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -49,6 +49,7 @@
#include <new>
#include <string.h>
#include <stdlib.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -192,6 +193,11 @@ private:
qint64 q_for_alignment_1;
double q_for_alignment_2;
};
+
+ bool isValidIterator(const const_iterator &i) const
+ {
+ return (i <= constEnd()) && (constBegin() <= i);
+ }
};
template <class T, int Prealloc>
@@ -355,6 +361,8 @@ inline void QVarLengthArray<T, Prealloc>::replace(int i, const T &t)
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
+
int offset = int(before - ptr);
if (n != 0) {
resize(s + n);
@@ -382,11 +390,14 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::erase(const_iterator abegin, const_iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVarLengthArray::insert", "The specified const_iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVarLengthArray::insert", "The specified const_iterator argument 'aend' is invalid");
+
int f = int(abegin - ptr);
int l = int(aend - ptr);
int n = l - f;
if (QTypeInfo<T>::isComplex) {
- qCopy(ptr + l, ptr + s, ptr + f);
+ std::copy(ptr + l, ptr + s, ptr + f);
T *i = ptr + s;
T *b = ptr + s - n;
while (i != b) {
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 4ff2b9f8e0..0f2acd6986 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -234,11 +234,15 @@ private:
friend class QRegion; // Optimization for QRegion::rects()
void reallocData(const int size, const int alloc, QArrayData::AllocationOptions options = QArrayData::Default);
+ void reallocData(const int sz) { reallocData(sz, d->alloc); }
void freeData(Data *d);
void defaultConstruct(T *from, T *to);
void copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom);
void destruct(T *from, T *to);
-
+ bool isValidIterator(const iterator &i) const
+ {
+ return (i <= d->end()) && (d->begin() <= i);
+ }
class AlignmentDummy { Data header; T array[1]; };
};
@@ -560,24 +564,25 @@ void QVector<T>::append(const T &t)
}
template <typename T>
-inline void QVector<T>::removeLast()
+void QVector<T>::removeLast()
{
Q_ASSERT(!isEmpty());
+ Q_ASSERT(d->alloc);
- if (d->alloc) {
- if (d->ref.isShared()) {
- reallocData(d->size - 1, int(d->alloc));
- return;
- }
- if (QTypeInfo<T>::isComplex)
- (d->data() + d->size - 1)->~T();
+ if (!d->ref.isShared()) {
--d->size;
+ if (QTypeInfo<T>::isComplex)
+ (d->data() + d->size)->~T();
+ } else {
+ reallocData(d->size - 1);
}
}
template <typename T>
typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVector::insert", "The specified iterator argument 'before' is invalid");
+
int offset = std::distance(d->begin(), before);
if (n != 0) {
const T copy(t);
@@ -611,6 +616,9 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
template <typename T>
typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVector::erase", "The specified iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVector::erase", "The specified iterator argument 'aend' is invalid");
+
const int itemsToErase = aend - abegin;
if (!itemsToErase)
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 40858e5336..8aab53998b 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -12,6 +12,8 @@ HEADERS += \
tools/qcache.h \
tools/qchar.h \
tools/qcollator_p.h \
+ tools/qcommandlineoption.h \
+ tools/qcommandlineparser.h \
tools/qcontainerfwd.h \
tools/qcryptographichash.h \
tools/qdatetime.h \
@@ -69,6 +71,8 @@ SOURCES += \
tools/qbytearray.cpp \
tools/qbytearraymatcher.cpp \
tools/qcollator.cpp \
+ tools/qcommandlineoption.cpp \
+ tools/qcommandlineparser.cpp \
tools/qcryptographichash.cpp \
tools/qdatetime.cpp \
tools/qeasingcurve.cpp \
diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf
index b47e02ff43..1233ae3d47 100644
--- a/src/dbus/doc/qtdbus.qdocconf
+++ b/src/dbus/doc/qtdbus.qdocconf
@@ -20,7 +20,7 @@ excludedirs += ../../../examples/widgets/doc
examplesinstallpath = dbus
-depends += qtcore
+depends += qtdoc qtcore
# The following parameters are for creating a qhp file, the qhelpgenerator
# program can convert the qhp file into a qch file which can be opened in
@@ -49,3 +49,6 @@ qhp.QtDBus.subprojects.classes.title = C++ Classes
qhp.QtDBus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes
qhp.QtDBus.subprojects.classes.selectors = class fake:headerfile
qhp.QtDBus.subprojects.classes.sortPages = true
+
+navigation.landingpage = "Qt D-Bus"
+navigation.cppclassespage = "Qt D-Bus C++ Classes"
diff --git a/src/dbus/doc/src/qtdbus-module.qdoc b/src/dbus/doc/src/qtdbus-module.qdoc
index fe3b11b926..ac9cac428b 100644
--- a/src/dbus/doc/src/qtdbus-module.qdoc
+++ b/src/dbus/doc/src/qtdbus-module.qdoc
@@ -32,6 +32,7 @@
to perform Inter-Process Communication using the \l{D-Bus} protocol.
\ingroup modules
+ \qtvariable dbus
\target The QDBus compiler
diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp
index 02ff40068b..5ab478e1bd 100644
--- a/src/dbus/qdbusabstractadaptor.cpp
+++ b/src/dbus/qdbusabstractadaptor.cpp
@@ -274,7 +274,7 @@ void QDBusAdaptorConnector::polish()
}
// sort the adaptor list
- qSort(adaptors);
+ std::sort(adaptors.begin(), adaptors.end());
}
void QDBusAdaptorConnector::relaySlot(void **argv)
@@ -307,15 +307,18 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void **
// break down the parameter list
QVector<int> types;
- int inputCount = qDBusParametersForMethod(mm, types);
- if (inputCount == -1)
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
+ if (inputCount == -1) {
// invalid signal signature
- // qDBusParametersForMethod has already complained
+ qWarning("QDBusAbstractAdaptor: Cannot relay signal %s::%s: %s",
+ senderMetaObject->className(), mm.methodSignature().constData(),
+ qPrintable(errorMsg));
return;
+ }
if (inputCount + 1 != types.count() ||
types.at(inputCount) == QDBusMetaTypeId::message()) {
// invalid signal signature
- // qDBusParametersForMethod has not yet complained about this one
qWarning("QDBusAbstractAdaptor: Cannot relay signal %s::%s",
senderMetaObject->className(), mm.methodSignature().constData());
return;
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index c702de141a..013896bd32 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -341,9 +341,9 @@ public:
};
// in qdbusmisc.cpp
-extern int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes);
+extern int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes, QString &errorMsg);
#endif // QT_BOOTSTRAPPED
-extern Q_DBUS_EXPORT int qDBusParametersForMethod(const QList<QByteArray> &parameters, QVector<int>& metaTypes);
+extern Q_DBUS_EXPORT int qDBusParametersForMethod(const QList<QByteArray> &parameters, QVector<int>& metaTypes, QString &errorMsg);
extern Q_DBUS_EXPORT bool qDBusCheckAsyncTag(const char *tag);
#ifndef QT_BOOTSTRAPPED
extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name);
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 3f25f02bee..e5f3fbdc53 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -721,7 +721,8 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags,
if (isAsync && returnType != QMetaType::Void)
continue;
- int inputCount = qDBusParametersForMethod(mm, metaTypes);
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, metaTypes, errorMsg);
if (inputCount == -1)
continue; // problem parsing
@@ -1312,7 +1313,8 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN
if (midx == -1)
return -1;
- int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params);
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params, errorMsg);
if ( inputCount == -1 || inputCount + 1 != params.count() )
return -1; // failed to parse or invalid arguments or output arguments
diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp
index d28d5598c6..5d3512845a 100644
--- a/src/dbus/qdbusmisc.cpp
+++ b/src/dbus/qdbusmisc.cpp
@@ -131,14 +131,14 @@ bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name)
// metaTypes.count() >= retval + 1 in all cases
//
// sig must be the normalised signature for the method
-int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes)
+int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes, QString &errorMsg)
{
- return qDBusParametersForMethod(mm.parameterTypes(), metaTypes);
+ return qDBusParametersForMethod(mm.parameterTypes(), metaTypes, errorMsg);
}
#endif // QT_BOOTSTRAPPED
-int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<int>& metaTypes)
+int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<int>& metaTypes, QString &errorMsg)
{
QDBusMetaTypeId::init();
metaTypes.clear();
@@ -151,8 +151,7 @@ int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<in
for ( ; it != end; ++it) {
const QByteArray &type = *it;
if (type.endsWith('*')) {
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // pointer?
+ errorMsg = QLatin1String("Pointers are not supported: ") + QLatin1String(type);
return -1;
}
@@ -162,8 +161,7 @@ int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<in
int id = QMetaType::type(basictype);
if (id == 0) {
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // invalid type in method parameter list
+ errorMsg = QLatin1String("Unregistered output type in parameter list: ") + QLatin1String(type);
return -1;
} else if (QDBusMetaType::typeToSignature(id) == 0)
return -1;
@@ -174,22 +172,22 @@ int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<in
}
if (seenMessage) { // && !type.endsWith('&')
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // non-output parameters after message or after output params
+ errorMsg = QLatin1String("Invalid method, non-output parameters after message or after output parameters: ") + QLatin1String(type);
return -1; // not allowed
}
int id = QMetaType::type(type);
if (id == QMetaType::UnknownType) {
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // invalid type in method parameter list
+ errorMsg = QLatin1String("Unregistered input type in parameter list: ") + QLatin1String(type);
return -1;
}
if (id == QDBusMetaTypeId::message())
seenMessage = true;
- else if (QDBusMetaType::typeToSignature(id) == 0)
+ else if (QDBusMetaType::typeToSignature(id) == 0) {
+ errorMsg = QLatin1String("Type not registered with QtDBus in parameter list: ") + QLatin1String(type);
return -1;
+ }
metaTypes.append(id);
++inputCount;
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp
index 49f9fc0cd8..e990e7d18b 100644
--- a/src/dbus/qdbuspendingcall.cpp
+++ b/src/dbus/qdbuspendingcall.cpp
@@ -221,7 +221,7 @@ void QDBusPendingCallPrivate::checkReceivedSignature()
return; // no signature to validate against
// can't use startsWith here because a null string doesn't start or end with an empty string
- if (!replyMessage.signature().indexOf(expectedReplySignature) == 0) {
+ if (replyMessage.signature().indexOf(expectedReplySignature) != 0) {
QString errorMsg = QLatin1String("Unexpected reply signature: got \"%1\", "
"expected \"%2\"");
replyMessage = QDBusMessage::createError(
diff --git a/src/dbus/qdbusxmlgenerator.cpp b/src/dbus/qdbusxmlgenerator.cpp
index 8c822162e4..c724ac573a 100644
--- a/src/dbus/qdbusxmlgenerator.cpp
+++ b/src/dbus/qdbusxmlgenerator.cpp
@@ -41,6 +41,7 @@
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qdebug.h>
#include "qdbusinterface_p.h" // for ANNOTATION_NO_WAIT
#include "qdbusabstractadaptor_p.h" // for QCLASSINFO_DBUS_*
@@ -159,17 +160,24 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
if (QDBusMetaType::signatureToType(typeName) == QVariant::Invalid)
xml += QString::fromLatin1(" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"%1\"/>\n")
.arg(typeNameToXml(QMetaType::typeName(typeId)));
- } else
+ } else {
+ qWarning() << "Unsupported return type" << typeId << QMetaType::typeName(typeId) << "in method" << mm.name();
continue;
+ }
}
- else if (typeId == QMetaType::UnknownType)
+ else if (typeId == QMetaType::UnknownType) {
+ qWarning() << "Invalid return type in method" << mm.name();
continue; // wasn't a valid type
+ }
QList<QByteArray> names = mm.parameterNames();
QVector<int> types;
- int inputCount = qDBusParametersForMethod(mm, types);
- if (inputCount == -1)
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
+ if (inputCount == -1) {
+ qWarning() << "Skipped method" << mm.name() << ":" << qPrintable(errorMsg);
continue; // invalid form
+ }
if (isSignal && inputCount + 1 != types.count())
continue; // signal with output arguments?
if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message())
diff --git a/src/gui/accessible/qaccessible2_p.h b/src/gui/accessible/qaccessible2_p.h
index 95f93e2431..458e32dd6d 100644
--- a/src/gui/accessible/qaccessible2_p.h
+++ b/src/gui/accessible/qaccessible2_p.h
@@ -127,12 +127,6 @@ public:
virtual int rowIndex() const = 0;
// Returns a boolean value indicating whether this cell is selected.
virtual bool isSelected() const = 0;
-
- // Gets the row and column indexes and extents of this cell accessible and whether or not it is selected.
- // ### Is this really needed??
- //
- // ### Maybe change to QSize cellSize(), we already have accessors for the row, column and selected
- virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const = 0;
// Returns a reference to the accessbile of the containing table.
virtual QAccessibleInterface* table() const = 0;
};
diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp
index 1b79c30b6c..a9a880e71f 100644
--- a/src/gui/accessible/qaccessiblecache.cpp
+++ b/src/gui/accessible/qaccessiblecache.cpp
@@ -60,7 +60,9 @@ QAccessible::Id QAccessibleCache::acquireId() const
static QAccessible::Id lastUsedId = FirstId;
while (idToInterface.contains(lastUsedId)) {
- if (lastUsedId == UINT_MAX) // (wrap back when when we reach UINT_MAX)
+ // (wrap back when when we reach UINT_MAX - 1)
+ // -1 because on Android -1 is taken for the "View" so just avoid it completely for consistency
+ if (lastUsedId == UINT_MAX - 1)
lastUsedId = FirstId;
else
++lastUsedId;
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 5073dd7f0f..ed30172376 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -48,3 +48,6 @@ exampledirs += ../../../examples/gui \
imagedirs += images \
../../../examples/gui/doc/images \
../../../doc/src/images \
+
+navigation.landingpage = "Qt GUI"
+navigation.cppclassespage = "Qt GUI C++ Classes"
diff --git a/src/gui/doc/snippets/code/doc_src_qtgui.pro b/src/gui/doc/snippets/code/doc_src_qtgui.pro
index 51bb6c74ff..e705555336 100644
--- a/src/gui/doc/snippets/code/doc_src_qtgui.pro
+++ b/src/gui/doc/snippets/code/doc_src_qtgui.pro
@@ -1,3 +1,7 @@
#! [0]
#include <QtGui>
#! [0]
+
+#! [1]
+QT -= gui
+#! [1]
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index 6c3e9a4938..d22c380145 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -29,6 +29,7 @@
\module QtGui
\title Qt GUI C++ Classes
\ingroup modules
+ \qtvariable gui
\brief The Qt GUI module provides the basic enablers for graphical
applications written with Qt.
@@ -45,7 +46,10 @@
\snippet code/doc_src_qtgui.pro 0
- See the \l {Qt GUI} page for more details.
+ If you use \l qmake to build your projects, \l{Qt GUI} is included by
+ default. To disable Qt GUI, add the following line to your \c .pro file:
+
+ \snippet code/doc_src_qtgui.pro 1
*/
@@ -71,7 +75,10 @@
\snippet code/doc_src_qtgui.pro 0
+ If you use \l qmake to build your projects, Qt GUI is included by
+ default. To disable Qt GUI, add the following line to your \c .pro file:
+ \snippet code/doc_src_qtgui.pro 1
\section1 Application Windows
@@ -172,11 +179,3 @@
\endlist
\endlist
*/
-
-/*!
- \group events
- \title Event Classes
- \ingroup groups
-
- \brief Classes that provide UI and input events.
-*/
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index cb4e45f1d0..c03d9b8e5d 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -781,6 +781,8 @@ bool QBmpHandler::write(const QImage &img)
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
image = img.convertToFormat(QImage::Format_ARGB32);
break;
case QImage::Format_RGB16:
@@ -788,6 +790,7 @@ bool QBmpHandler::write(const QImage &img)
case QImage::Format_RGB666:
case QImage::Format_RGB555:
case QImage::Format_RGB444:
+ case QImage::Format_RGBX8888:
image = img.convertToFormat(QImage::Format_RGB32);
break;
default:
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index aef7324171..cb508ae6c7 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -1068,7 +1068,6 @@ void QIcon::setThemeName(const QString &name)
*/
QString QIcon::themeName()
{
- QIconLoader::instance()->ensureInitialized();
return QIconLoader::instance()->themeName();
}
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index e81bea69d6..f1a78b508c 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -62,6 +62,10 @@ public:
QIcon();
QIcon(const QPixmap &pixmap);
QIcon(const QIcon &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QIcon(QIcon &&other)
+ :d(0) { qSwap(d, other.d); }
+#endif
explicit QIcon(const QString &fileName); // file or resource name
explicit QIcon(QIconEngine *engine);
~QIcon();
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 105dc26c9b..d202d62957 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -128,6 +128,7 @@ void QIconLoader::ensureInitialized()
QIconLoader *QIconLoader::instance()
{
+ iconLoaderInstance()->ensureInitialized();
return iconLoaderInstance();
}
@@ -368,17 +369,14 @@ bool QIconLoaderEngine::hasIcon() const
// Lazily load the icon
void QIconLoaderEngine::ensureLoaded()
{
-
- iconLoaderInstance()->ensureInitialized();
-
- if (!(iconLoaderInstance()->themeKey() == m_key)) {
+ if (!(QIconLoader::instance()->themeKey() == m_key)) {
while (!m_entries.isEmpty())
delete m_entries.takeLast();
Q_ASSERT(m_entries.size() == 0);
- m_entries = iconLoaderInstance()->loadIcon(m_iconName);
- m_key = iconLoaderInstance()->themeKey();
+ m_entries = QIconLoader::instance()->loadIcon(m_iconName);
+ m_key = QIconLoader::instance()->themeKey();
}
}
@@ -565,7 +563,7 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
{
QIconEngine::AvailableSizesArgument &arg
= *reinterpret_cast<QIconEngine::AvailableSizesArgument*>(data);
- const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
+ const QList<QIconDirInfo> directoryKey = QIconLoader::instance()->theme().keyList();
arg.sizes.clear();
// Gets all sizes from the DirectoryInfo entries
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 98f3aeeeb9..8e5f6391a7 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -212,6 +212,16 @@ bool QImageData::checkForAlphaPixels() const
}
} break;
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied: {
+ uchar *bits = data;
+ for (int y=0; y<height && !has_alpha_pixels; ++y) {
+ for (int x=0; x<width; ++x)
+ has_alpha_pixels |= bits[x*4+3] != 0xff;
+ bits += bytes_per_line;
+ }
+ } break;
+
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB8565_Premultiplied: {
uchar *bits = data;
@@ -621,9 +631,9 @@ bool QImageData::checkForAlphaPixels() const
/*!
\enum QImage::Format
- The following image formats are available in Qt. Values greater
- than QImage::Format_RGB16 were added in Qt 4.4. See the notes
- after the table.
+ The following image formats are available in Qt. Values from Format_ARGB8565_Premultiplied
+ to Format_ARGB4444_Premultiplied were added in Qt 4.4. Values Format_RGBX8888, Format_RGBA8888
+ and Format_RGBA8888_Premultiplied were added in Qt 5.2. See the notes after the table.
\value Format_Invalid The image is invalid.
\value Format_Mono The image is stored using 1-bit per pixel. Bytes are
@@ -665,6 +675,15 @@ bool QImageData::checkForAlphaPixels() const
The unused bits are always zero.
\value Format_ARGB4444_Premultiplied The image is stored using a
premultiplied 16-bit ARGB format (4-4-4-4).
+ \value Format_RGBX8888 The image is stored using a 32-bit byte-ordered RGB(x) format (8-8-8-8).
+ This is the same as the Format_RGBA8888 except alpha must always be 255.
+ \value Format_RGBA8888 The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8).
+ Unlike ARGB32 this is a byte-ordered format, which means the 32bit
+ encoding differs between big endian and little endian architectures,
+ being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors
+ is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA.
+ \value Format_RGBA8888_Premultiplied The image is stored using a
+ premultiplied 32-bit byte-ordered RGBA format (8-8-8-8).
\note Drawing into a QImage with QImage::Format_Indexed8 is not
supported.
@@ -1663,9 +1682,12 @@ void QImage::fill(uint pixel)
return;
}
- if (d->format == Format_RGB32)
+ if (d->format == Format_RGB32 || d->format == Format_RGBX8888)
pixel |= 0xff000000;
+ if (d->format == Format_RGBX8888 || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied)
+ pixel = ARGB2RGBA(pixel);
+
qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
0, 0, d->width, d->height, d->bytes_per_line);
}
@@ -1716,7 +1738,7 @@ void QImage::fill(const QColor &color)
if (d->depth == 32) {
uint pixel = color.rgba();
- if (d->format == QImage::Format_ARGB32_Premultiplied)
+ if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied)
pixel = PREMUL(pixel);
fill((uint) pixel);
@@ -1871,8 +1893,8 @@ typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFla
static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(src->format == QImage::Format_ARGB32);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
@@ -1912,6 +1934,191 @@ static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversio
return true;
}
+static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | *src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ quint32 *rgb_data = (quint32 *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const quint32 *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = ARGB2RGBA(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_ARGB32)
+ data->format = QImage::Format_RGBA8888;
+ else
+ data->format = QImage::Format_RGBA8888_Premultiplied;
+ return true;
+}
+
+static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(PREMUL(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888 || data->format == QImage::Format_RGBA8888_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = RGBA2ARGB(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_RGBA8888_Premultiplied)
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ else if (data->format == QImage::Format_RGBX8888)
+ data->format = QImage::Format_RGB32;
+ else
+ data->format = QImage::Format_ARGB32;
+ return true;
+}
+
+static void convert_RGBA_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = PREMUL(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBA8888);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = PREMUL(RGBA2ARGB(*rgb_data));
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ return true;
+}
+
static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_Indexed8);
@@ -2099,8 +2306,8 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl
static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
@@ -2123,20 +2330,164 @@ static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt:
static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | INV_PREMUL(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | INV_PREMUL(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(INV_PREMUL(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBX8888);
Q_ASSERT(dest->format == QImage::Format_RGB32);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
const int src_pad = (src->bytes_per_line >> 2) - src->width;
const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data) | 0xff000000;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data | 0xff000000);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
const QRgb *src_data = (QRgb *) src->data;
QRgb *dest_data = (QRgb *) dest->data;
for (int i = 0; i < src->height; ++i) {
const QRgb *end = src_data + src->width;
while (src_data < end) {
- *dest_data = 0xff000000 | INV_PREMUL(*src_data);
+ *dest_data = INV_PREMUL(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | INV_PREMUL(RGBA2ARGB(*src_data));
++src_data;
++dest_data;
}
@@ -2188,6 +2539,33 @@ static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::Im
}
}
+static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ return mask_alpha_converter(dest, src, flags);
+#else
+ Q_UNUSED(flags);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = *src_data | 0x000000ff;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+#endif
+}
+
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2941,6 +3319,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_Mono
@@ -2960,6 +3341,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_MonoLSB
@@ -2979,6 +3363,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_Indexed8
@@ -2998,7 +3385,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_generic,
convert_generic,
convert_generic,
- convert_generic
+ convert_generic,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA
}, // Format_RGB32
{
@@ -3017,7 +3407,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_generic,
convert_generic,
convert_generic,
- convert_generic
+ convert_generic,
+ convert_ARGB_to_RGBx,
+ convert_ARGB_to_RGBA,
+ convert_ARGB_to_RGBA_PM,
}, // Format_ARGB32
{
@@ -3036,7 +3429,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0
+ 0,
+ convert_ARGB_PM_to_RGBx,
+ convert_ARGB_PM_to_RGBA,
+ convert_ARGB_to_RGBA,
}, // Format_ARGB32_Premultiplied
{
@@ -3059,6 +3455,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB16
@@ -3078,6 +3477,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_ARGB8565_Premultiplied
@@ -3097,6 +3499,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB666
@@ -3116,6 +3521,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_ARGB6666_Premultiplied
@@ -3139,6 +3547,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB555
@@ -3158,6 +3569,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_ARGB8555_Premultiplied
@@ -3177,6 +3591,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB888
@@ -3196,6 +3613,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB444
@@ -3215,20 +3635,97 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
0
- } // Format_ARGB4444_Premultiplied
+ }, // Format_ARGB4444_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+ mask_alpha_converter_RGBx,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ 0,
+ convert_ARGB_to_ARGB_PM,
+#else
+ 0,
+ 0
+#endif
+ }, // Format_RGBA8888
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_PM_to_RGB,
+ convert_RGBA_PM_to_ARGB,
+ convert_RGBA_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_ARGB_PM_to_RGB,
+ convert_ARGB_PM_to_ARGB,
+ 0,
+#else
+ 0,
+ 0,
+ 0
+#endif
+ } // Format_RGBA8888_Premultiplied
};
static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
0,
@@ -3247,6 +3744,9 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ 0,
+ 0,
+ 0,
}, // Format_Indexed8
{
0,
@@ -3265,7 +3765,10 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- }, // Format_ARGB32
+ 0,
+ 0,
+ 0,
+ }, // Format_RGB32
{
0,
0,
@@ -3283,37 +3786,118 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ 0,
+ convert_ARGB_to_RGBA_inplace,
+ 0,
}, // Format_ARGB32
{
- 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,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBA_inplace
}, // Format_ARGB32_Premultiplied
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- } // Format_ARGB4444_Premultiplied
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_PM_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBA8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ } // Format_RGBA8888_Premultiplied
};
void qInitImageConversions()
@@ -3633,6 +4217,10 @@ QRgb QImage::pixel(int x, int y) const
case Format_ARGB32: // Keep old behaviour.
case Format_ARGB32_Premultiplied:
return reinterpret_cast<const QRgb *>(s)[x];
+ case Format_RGBX8888:
+ case Format_RGBA8888: // Match ARGB32 behavior.
+ case Format_RGBA8888_Premultiplied:
+ return RGBA2ARGB(reinterpret_cast<const quint32 *>(s)[x]);
case Format_RGB16:
return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]);
default:
@@ -3716,6 +4304,13 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
case Format_RGB16:
((quint16 *)s)[x] = qConvertRgb32To16(INV_PREMUL(index_or_rgb));
return;
+ case Format_RGBX8888:
+ ((uint *)s)[x] = ARGB2RGBA(index_or_rgb | 0xff000000);
+ return;
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+ ((uint *)s)[x] = ARGB2RGBA(index_or_rgb);
+ return;
case Format_Invalid:
case NImageFormats:
Q_ASSERT(false);
@@ -3756,6 +4351,11 @@ bool QImage::allGray() const
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ case Format_RGBX8888:
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+#endif
for (int j = 0; j < d->height; ++j) {
const QRgb *b = (const QRgb *)constScanLine(j);
for (int i = 0; i < d->width; ++i) {
@@ -4330,6 +4930,11 @@ QImage QImage::rgbSwapped() const
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ case Format_RGBX8888:
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+#endif
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
@@ -5373,7 +5978,11 @@ QImage QImage::alphaChannel() const
}
} else {
QImage alpha32 = *this;
- if (d->format != Format_ARGB32 && d->format != Format_ARGB32_Premultiplied)
+ bool canSkipConversion = (d->format == Format_ARGB32 || d->format == Format_ARGB32_Premultiplied);
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ canSkipConversion = canSkipConversion || (d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied);
+#endif
+ if (!canSkipConversion)
alpha32 = convertToFormat(Format_ARGB32);
const uchar *src_data = alpha32.d->data;
@@ -5408,6 +6017,8 @@ bool QImage::hasAlphaChannel() const
|| d->format == Format_ARGB8555_Premultiplied
|| d->format == Format_ARGB6666_Premultiplied
|| d->format == Format_ARGB4444_Premultiplied
+ || d->format == Format_RGBA8888
+ || d->format == Format_RGBA8888_Premultiplied
|| (d->has_alpha_clut && (d->format == Format_Indexed8
|| d->format == Format_Mono
|| d->format == Format_MonoLSB)));
@@ -5434,6 +6045,7 @@ int QImage::bitPlaneCount() const
case QImage::Format_Invalid:
break;
case QImage::Format_RGB32:
+ case QImage::Format_RGBX8888:
bpc = 24;
break;
case QImage::Format_RGB666:
@@ -5457,9 +6069,11 @@ int QImage::bitPlaneCount() const
static QImage smoothScaled(const QImage &source, int w, int h) {
QImage src = source;
- if (src.format() == QImage::Format_ARGB32)
- src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- else if (src.depth() < 32) {
+ bool canSkipConversion = (src.format() == QImage::Format_RGB32 || src.format() == QImage::Format_ARGB32_Premultiplied);
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ canSkipConversion = canSkipConversion || (src.format() == QImage::Format_RGBX8888 || src.format() == QImage::Format_RGBA8888_Premultiplied);
+#endif
+ if (!canSkipConversion) {
if (src.hasAlphaChannel())
src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
else
@@ -5480,6 +6094,9 @@ static QImage rotated90(const QImage &image) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
qt_memrotate270(reinterpret_cast<const quint32*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint32*>(out.bits()),
@@ -5539,6 +6156,9 @@ static QImage rotated270(const QImage &image) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
qt_memrotate90(reinterpret_cast<const quint32*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint32*>(out.bits()),
@@ -5684,6 +6304,9 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
case QImage::Format_RGB444:
target_format = Format_ARGB4444_Premultiplied;
break;
+ case QImage::Format_RGBX8888:
+ target_format = Format_RGBA8888_Premultiplied;
+ break;
default:
target_format = Format_ARGB32_Premultiplied;
break;
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 50d4bc7666..02f0c18243 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -110,6 +110,9 @@ public:
Format_RGB888,
Format_RGB444,
Format_ARGB4444_Premultiplied,
+ Format_RGBX8888,
+ Format_RGBA8888,
+ Format_RGBA8888_Premultiplied,
#if 0
// reserved for future use
Format_RGB15,
@@ -139,6 +142,11 @@ public:
explicit QImage(const QString &fileName, const char *format = 0);
QImage(const QImage &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QImage(QImage &&other)
+ : QPaintDevice(), d(0)
+ { qSwap(d, other.d); }
+#endif
~QImage();
QImage &operator=(const QImage &);
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 18c686e917..36f117df60 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -128,6 +128,9 @@ inline int qt_depthForFormat(QImage::Format format)
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
depth = 32;
break;
case QImage::Format_RGB555:
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index ec55cb85a3..5c5b1fa0be 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -150,6 +150,8 @@
#include <private/qgifhandler_p.h>
#endif
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_IMAGEFORMATPLUGIN
@@ -199,7 +201,7 @@ static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
#endif
#ifndef QT_NO_IMAGEFORMAT_JPEG
{_qt_JpgFormat, "jpg", "image/jpeg"},
- {_qt_JpegFormat, "jpeg"},
+ {_qt_JpegFormat, "jpeg", "image/jpeg"},
#endif
#ifdef QT_BUILTIN_GIF_READER
{_qt_GifFormat, "gif", "image/gif"},
@@ -1494,7 +1496,7 @@ QList<QByteArray> QImageReader::supportedImageFormats()
for (QSet<QByteArray>::ConstIterator it = formats.constBegin(); it != formats.constEnd(); ++it)
sortedFormats << *it;
- qSort(sortedFormats);
+ std::sort(sortedFormats.begin(), sortedFormats.end());
return sortedFormats;
}
@@ -1521,7 +1523,7 @@ QList<QByteArray> QImageReader::supportedMimeTypes()
for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it)
sortedMimeTypes << *it;
- qSort(sortedMimeTypes);
+ std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end());
return sortedMimeTypes;
}
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index a27dc9d16f..c502a01df5 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -123,6 +123,8 @@
#include <private/qgifhandler_p.h>
#endif
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_IMAGEFORMATPLUGIN
@@ -755,7 +757,7 @@ QList<QByteArray> QImageWriter::supportedImageFormats()
for (QSet<QByteArray>::ConstIterator it = formats.constBegin(); it != formats.constEnd(); ++it)
sortedFormats << *it;
- qSort(sortedFormats);
+ std::sort(sortedFormats.begin(), sortedFormats.end());
return sortedFormats;
}
@@ -797,7 +799,7 @@ QList<QByteArray> QImageWriter::supportedMimeTypes()
for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it)
sortedMimeTypes << *it;
- qSort(sortedMimeTypes);
+ std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end());
return sortedMimeTypes;
}
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index 1071ed754b..e7fbb2a6a9 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -59,6 +59,8 @@
#include "qregion.h"
#include "qdebug.h"
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
void qt_format_text(const QFont &fnt, const QRectF &_r,
@@ -1798,7 +1800,7 @@ QList<QByteArray> QPictureIO::inputFormats()
result.append(p->format);
}
}
- qSort(result);
+ std::sort(result.begin(), result.end());
return result;
}
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index d66bc409e6..93efe2e696 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -279,6 +279,9 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat =
Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p)
{
+ if (p.isNull())
+ return 0;
+
QBitmap maskBitmap = p.mask();
if (maskBitmap.isNull()) {
maskBitmap = QBitmap(p.size());
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 6fc41df77c..39f63a620c 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -274,12 +274,15 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
case QImage::Format_RGB555:
case QImage::Format_RGB888:
case QImage::Format_RGB444:
+ case QImage::Format_RGBX8888:
image = image.convertToFormat(QImage::Format_RGB32);
break;
case QImage::Format_ARGB8565_Premultiplied:
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
image = image.convertToFormat(QImage::Format_ARGB32);
break;
default:
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index a7936f915d..3bd8ca92b4 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -1092,7 +1092,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const
return false;
QImage image;
- if (sourceImage.depth() != 32)
+ if (sourceImage.format() != QImage::Format_RGB32 || sourceImage.format() != QImage::Format_ARGB32 || sourceImage.format() != QImage::Format_ARGB32_Premultiplied)
image = sourceImage.convertToFormat(QImage::Format_RGB32);
else
image = sourceImage;
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp
index d5d742c9b3..955d72f2ca 100644
--- a/src/gui/itemmodels/qstandarditemmodel.cpp
+++ b/src/gui/itemmodels/qstandarditemmodel.cpp
@@ -55,6 +55,7 @@
#include <private/qstandarditemmodel_p.h>
#include <qdebug.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -254,10 +255,10 @@ void QStandardItemPrivate::sortChildren(int column, Qt::SortOrder order)
if (order == Qt::AscendingOrder) {
QStandardItemModelLessThan lt;
- qStableSort(sortable.begin(), sortable.end(), lt);
+ std::stable_sort(sortable.begin(), sortable.end(), lt);
} else {
QStandardItemModelGreaterThan gt;
- qStableSort(sortable.begin(), sortable.end(), gt);
+ std::stable_sort(sortable.begin(), sortable.end(), gt);
}
QModelIndexList changedPersistentIndexesFrom, changedPersistentIndexesTo;
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 3c019fc5b5..d9bcbf316f 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -56,6 +56,7 @@ HEADERS += \
kernel/qpalette.h \
kernel/qshortcutmap_p.h \
kernel/qsessionmanager.h \
+ kernel/qsessionmanager_p.h \
kernel/qwindowdefs.h \
kernel/qscreen.h \
kernel/qscreen_p.h \
@@ -66,7 +67,8 @@ HEADERS += \
kernel/qplatformdialoghelper.h \
kernel/qplatformservices.h \
kernel/qplatformscreenpageflipper.h \
- kernel/qplatformsystemtrayicon.h
+ kernel/qplatformsystemtrayicon.h \
+ kernel/qplatformsessionmanager.h
SOURCES += \
kernel/qclipboard_qpa.cpp \
@@ -118,7 +120,8 @@ SOURCES += \
kernel/qplatformdialoghelper.cpp \
kernel/qplatformservices.cpp \
kernel/qplatformscreenpageflipper.cpp \
- kernel/qplatformsystemtrayicon_qpa.cpp
+ kernel/qplatformsystemtrayicon_qpa.cpp \
+ kernel/qplatformsessionmanager.cpp
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index fa289bbf8b..e11c4671e6 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -45,7 +45,6 @@
#include "qpa/qplatformintegration.h"
#include "qpa/qplatformdrag.h"
#include "private/qevent_p.h"
-#include "private/qkeysequence_p.h"
#include "qdebug.h"
#include "qmimedata.h"
#include "private/qdnd_p.h"
@@ -654,6 +653,9 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta
event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the
direction.
+ The phase() is initialized to Qt::ScrollUpdate. Use the other constructor
+ to specify the phase explicitly.
+
\sa posF(), globalPosF(), angleDelta(), pixelDelta()
*/
@@ -661,9 +663,38 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta),
- angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons)
+ angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(Qt::ScrollUpdate)
{}
+/*!
+ Constructs a wheel event object.
+
+ The \a pos provides the location of the mouse cursor
+ within the window. The position in global coordinates is specified
+ by \a globalPos.
+
+ \a pixelDelta contains the scrolling distance in pixels on screen, while
+ \a angleDelta contains the wheel rotation distance. \a pixelDelta is
+ optional and can be null.
+
+ The mouse and keyboard states at the time of the event are specified by
+ \a buttons and \a modifiers.
+
+ For backwards compatibility, the event can also hold monodirectional wheel
+ event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the
+ direction.
+
+ The scrolling phase of the event is specified by \a phase.
+
+ \sa posF(), globalPosF(), angleDelta(), pixelDelta(), phase()
+*/
+
+QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
+ QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase)
+ : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta),
+ angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(phase)
+{}
#endif // QT_NO_WHEELEVENT
@@ -794,6 +825,13 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
\sa posF()
*/
+/*!
+ \fn Qt::ScrollPhase QWheelEvent::phase() const
+ \since 5.2
+
+ Returns the scrolling phase of this wheel event.
+*/
+
/*!
\class QKeyEvent
@@ -997,50 +1035,9 @@ bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const
{
//The keypad and group switch modifier should not make a difference
uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier | Qt::GroupSwitchModifier);
- const uint platform = QKeySequencePrivate::currentKeyPlatforms();
-
- uint N = QKeySequencePrivate::numberOfKeyBindings;
- int first = 0;
- int last = N - 1;
- while (first <= last) {
- int mid = (first + last) / 2;
- QKeyBinding midVal = QKeySequencePrivate::keyBindings[mid];
-
- if (searchkey > midVal.shortcut){
- first = mid + 1; // Search in top half
- }
- else if (searchkey < midVal.shortcut){
- last = mid - 1; // Search in bottom half
- }
- else {
- //found correct shortcut value, now we must check for platform match
- if ((midVal.platform & platform) && (midVal.standardKey == matchKey)) {
- return true;
- } else { //We may have several equal values for different platforms, so we must search in both directions
-
- //search forward
- for ( unsigned int i = mid + 1 ; i < N - 1 ; ++i) {
- QKeyBinding current = QKeySequencePrivate::keyBindings[i];
- if (current.shortcut != searchkey)
- break;
- else if (current.platform & platform && current.standardKey == matchKey)
- return true;
- }
-
- //search back
- for ( int i = mid - 1 ; i >= 0 ; --i) {
- QKeyBinding current = QKeySequencePrivate::keyBindings[i];
- if (current.shortcut != searchkey)
- break;
- else if (current.platform & platform && current.standardKey == matchKey)
- return true;
- }
- return false; //we could not find it among the matching keySequences
- }
- }
- }
- return false; //we could not find matching keySequences at all
+ const QList<QKeySequence> bindings = QKeySequence::keyBindings(matchKey);
+ return bindings.contains(QKeySequence(searchkey));
}
#endif // QT_NO_SHORTCUT
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 7142450322..0c1cf70420 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -176,6 +176,9 @@ public:
QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
+ QWheelEvent(const QPointF &pos, const QPointF& globalPos,
+ QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase);
~QWheelEvent();
@@ -198,6 +201,9 @@ public:
inline const QPointF &globalPosF() const { return g; }
inline Qt::MouseButtons buttons() const { return mouseState; }
+
+ inline Qt::ScrollPhase phase() const { return Qt::ScrollPhase(ph); }
+
protected:
QPointF p;
QPointF g;
@@ -206,7 +212,8 @@ protected:
int qt4D;
Qt::Orientation qt4O;
Qt::MouseButtons mouseState;
- int reserved;
+ uint ph : 2;
+ int reserved : 30;
};
#endif
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 6653d5a207..1186cc2905 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -101,6 +101,8 @@
# include <QtCore/QLibraryInfo>
#endif // Q_OS_WIN && !Q_OS_WINCE
+#include <ctype.h>
+
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT bool qt_is_gui_used = true;
@@ -215,6 +217,106 @@ static inline bool isPopupWindow(const QWindow *w)
return (w->flags() & Qt::WindowType_Mask) == Qt::Popup;
}
+// Geometry specification for top level windows following the convention of the
+// -geometry command line arguments in X11 (see XParseGeometry).
+struct QWindowGeometrySpecification
+{
+ QWindowGeometrySpecification() : corner(Qt::TopLeftCorner), xOffset(-1), yOffset(-1), width(-1), height(-1) {}
+ static QWindowGeometrySpecification fromArgument(const QByteArray &a);
+ QRect apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const;
+ inline QRect apply(const QRect &windowGeometry, const QWindow *window) const
+ { return apply(windowGeometry, window->minimumSize(), window->maximumSize(), window->screen()->virtualGeometry()); }
+
+ Qt::Corner corner;
+ int xOffset;
+ int yOffset;
+ int width;
+ int height;
+};
+
+// Parse a token of a X11 geometry specification "200x100+10-20".
+static inline int nextGeometryToken(const QByteArray &a, int &pos, char *op)
+{
+ *op = 0;
+ const int size = a.size();
+ if (pos >= size)
+ return -1;
+
+ *op = a.at(pos);
+ if (*op == '+' || *op == '-' || *op == 'x')
+ pos++;
+ else if (isdigit(*op))
+ *op = 'x'; // If it starts with a digit, it is supposed to be a width specification.
+ else
+ return -1;
+
+ const int numberPos = pos;
+ for ( ; pos < size && isdigit(a.at(pos)); ++pos) ;
+
+ bool ok;
+ const int result = a.mid(numberPos, pos - numberPos).toInt(&ok);
+ return ok ? result : -1;
+}
+
+QWindowGeometrySpecification QWindowGeometrySpecification::fromArgument(const QByteArray &a)
+{
+ QWindowGeometrySpecification result;
+ int pos = 0;
+ for (int i = 0; i < 4; ++i) {
+ char op;
+ const int value = nextGeometryToken(a, pos, &op);
+ if (value < 0)
+ break;
+ switch (op) {
+ case 'x':
+ (result.width >= 0 ? result.height : result.width) = value;
+ break;
+ case '+':
+ case '-':
+ if (result.xOffset >= 0) {
+ result.yOffset = value;
+ if (op == '-')
+ result.corner = result.corner == Qt::TopRightCorner ? Qt::BottomRightCorner : Qt::BottomLeftCorner;
+ } else {
+ result.xOffset = value;
+ if (op == '-')
+ result.corner = Qt::TopRightCorner;
+ }
+ }
+ }
+ return result;
+}
+
+QRect QWindowGeometrySpecification::apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const
+{
+ QRect result = windowGeometry;
+ if (width >= 0 || height >= 0) {
+ QSize size = windowGeometry.size();
+ if (width >= 0)
+ size.setWidth(qBound(windowMinimumSize.width(), width, windowMaximumSize.width()));
+ if (height >= 0)
+ size.setHeight(qBound(windowMinimumSize.height(), height, windowMaximumSize.height()));
+ result.setSize(size);
+ }
+ if (xOffset >= 0 || yOffset >= 0) {
+ QPoint topLeft = windowGeometry.topLeft();
+ if (xOffset >= 0) {
+ topLeft.setX(corner == Qt::TopLeftCorner || corner == Qt::BottomLeftCorner ?
+ xOffset :
+ qMax(availableGeometry.right() - result.width() - xOffset, availableGeometry.left()));
+ }
+ if (yOffset >= 0) {
+ topLeft.setY(corner == Qt::TopLeftCorner || corner == Qt::TopRightCorner ?
+ yOffset :
+ qMax(availableGeometry.bottom() - result.height() - yOffset, availableGeometry.top()));
+ }
+ result.moveTopLeft(topLeft);
+ }
+ return result;
+}
+
+static QWindowGeometrySpecification windowGeometrySpecification;
+
/*!
\class QGuiApplication
\brief The QGuiApplication class manages the GUI application's control
@@ -785,14 +887,14 @@ QString QGuiApplication::platformName()
*QGuiApplicationPrivate::platform_name : QString();
}
-static void init_platform(const QString &pluginArgument, const QString &platformPluginPath)
+static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, int &argc, char **argv)
{
// Split into platform name and arguments
QStringList arguments = pluginArgument.split(QLatin1Char(':'));
const QString name = arguments.takeFirst().toLower();
// Create the platform integration.
- QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, platformPluginPath);
+ QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
if (QGuiApplicationPrivate::platform_integration) {
QGuiApplicationPrivate::platform_name = new QString(name);
} else {
@@ -910,6 +1012,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
} else if (arg == "-platform") {
if (++i < argc)
platformName = argv[i];
+ } else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) {
+ if (++i < argc)
+ windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
} else {
argv[j++] = argv[i];
}
@@ -920,7 +1025,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
argc = j;
}
- init_platform(QLatin1String(platformName), platformPluginPath);
+ init_platform(QLatin1String(platformName), platformPluginPath, argc, argv);
}
@@ -963,7 +1068,10 @@ void QGuiApplicationPrivate::init()
bool doGrabUnderDebugger = false;
QList<QByteArray> pluginList;
// Get command line params
-
+#ifndef QT_NO_SESSIONMANAGER
+ QString session_id;
+ QString session_key;
+#endif
int j = argc ? 1 : 0;
for (int i=1; i<argc; i++) {
if (argv[i] && *argv[i] != '-') {
@@ -1313,7 +1421,7 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowScreenChangedEvent *>(e));
break;
case QWindowSystemInterfacePrivate::ApplicationStateChanged:
- QGuiApplicationPrivate::processApplicationStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e));
+ QGuiApplicationPrivate::setApplicationState(static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e)->newState);
break;
case QWindowSystemInterfacePrivate::FlushEvents:
QWindowSystemInterface::deferredFlushWindowSystemEvents();
@@ -1375,6 +1483,8 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
static_cast<QWindowSystemInterfacePrivate::ContextMenuEvent *>(e));
break;
#endif
+ case QWindowSystemInterfacePrivate::EnterWhatsThisMode:
+ QGuiApplication::postEvent(QGuiApplication::instance(), new QEvent(QEvent::EnterWhatsThisMode));
default:
qWarning() << "Unknown user input event type:" << e->type;
break;
@@ -1531,7 +1641,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
return;
}
- QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers);
+ QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers, e->phase);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
#endif /* ifndef QT_NO_WHEELEVENT */
@@ -1641,10 +1751,7 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate
QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)),
qApp, SLOT(_q_updateFocusObject(QObject*)));
} else if (!platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
- QEvent appActivate(QEvent::ApplicationActivate);
- qApp->sendSpontaneousEvent(qApp, &appActivate);
- QApplicationStateChangeEvent appState(Qt::ApplicationActive);
- qApp->sendSpontaneousEvent(qApp, &appState);
+ setApplicationState(Qt::ApplicationActive);
}
if (QGuiApplicationPrivate::focus_window) {
@@ -1653,10 +1760,7 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate
QObject::connect(QGuiApplicationPrivate::focus_window, SIGNAL(focusObjectChanged(QObject*)),
qApp, SLOT(_q_updateFocusObject(QObject*)));
} else if (!platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
- QEvent appActivate(QEvent::ApplicationDeactivate);
- qApp->sendSpontaneousEvent(qApp, &appActivate);
- QApplicationStateChangeEvent appState(Qt::ApplicationInactive);
- qApp->sendSpontaneousEvent(qApp, &appState);
+ setApplicationState(Qt::ApplicationInactive);
}
if (self) {
@@ -1692,29 +1796,6 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
}
}
-void QGuiApplicationPrivate::processApplicationStateChangedEvent(QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e)
-{
- if (e->newState == applicationState)
- return;
- applicationState = e->newState;
-
- switch (e->newState) {
- case Qt::ApplicationActive: {
- QEvent appActivate(QEvent::ApplicationActivate);
- qApp->sendSpontaneousEvent(qApp, &appActivate);
- break; }
- case Qt::ApplicationInactive: {
- QEvent appDeactivate(QEvent::ApplicationDeactivate);
- qApp->sendSpontaneousEvent(qApp, &appDeactivate);
- break; }
- default:
- break;
- }
-
- QApplicationStateChangeEvent event(applicationState);
- qApp->sendSpontaneousEvent(qApp, &event);
-}
-
void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce)
{
if (self)
@@ -2398,6 +2479,11 @@ void QGuiApplication::setPalette(const QPalette &pal)
applicationResourceFlags |= ApplicationPaletteExplicitlySet;
}
+QRect QGuiApplicationPrivate::applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window)
+{
+ return windowGeometrySpecification.apply(windowGeometry, window);
+}
+
/*!
Returns the default application font.
@@ -2520,6 +2606,58 @@ bool QGuiApplicationPrivate::shouldQuitInternal(const QWindowList &processedWind
}
/*!
+ \since 5.2
+ \fn Qt::ApplicationState QGuiApplication::applicationState()
+
+
+ Returns the current state of the application.
+
+ You can react to application state changes to perform actions such as
+ stopping/resuming CPU-intensive tasks, freeing/loading resources or
+ saving/restoring application data.
+ */
+
+Qt::ApplicationState QGuiApplication::applicationState()
+{
+ return QGuiApplicationPrivate::applicationState;
+}
+
+/*!
+ \since 5.2
+ \fn void QGuiApplication::applicationStateChanged(Qt::ApplicationState state)
+
+ This signal is emitted when the \a state of the application changes.
+
+ \sa applicationState()
+*/
+
+void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state)
+{
+ if (applicationState == state)
+ return;
+
+ applicationState = state;
+
+ switch (state) {
+ case Qt::ApplicationActive: {
+ QEvent appActivate(QEvent::ApplicationActivate);
+ QCoreApplication::sendSpontaneousEvent(qApp, &appActivate);
+ break; }
+ case Qt::ApplicationInactive: {
+ QEvent appDeactivate(QEvent::ApplicationDeactivate);
+ QCoreApplication::sendSpontaneousEvent(qApp, &appDeactivate);
+ break; }
+ default:
+ break;
+ }
+
+ QApplicationStateChangeEvent event(applicationState);
+ QCoreApplication::sendSpontaneousEvent(qApp, &event);
+
+ emit qApp->applicationStateChanged(applicationState);
+}
+
+/*!
\since 4.2
\fn void QGuiApplication::commitDataRequest(QSessionManager &manager)
@@ -2632,13 +2770,13 @@ bool QGuiApplication::isSessionRestored() const
QString QGuiApplication::sessionId() const
{
Q_D(const QGuiApplication);
- return d->session_id;
+ return d->session_manager->sessionId();
}
QString QGuiApplication::sessionKey() const
{
Q_D(const QGuiApplication);
- return d->session_key;
+ return d->session_manager->sessionKey();
}
bool QGuiApplication::isSavingSession() const
@@ -2647,12 +2785,12 @@ bool QGuiApplication::isSavingSession() const
return d->is_saving_session;
}
-void QGuiApplicationPrivate::commitData(QSessionManager& manager)
+void QGuiApplicationPrivate::commitData()
{
Q_Q(QGuiApplication);
is_saving_session = true;
- emit q->commitDataRequest(manager);
- if (manager.allowsInteraction()) {
+ emit q->commitDataRequest(*session_manager);
+ if (session_manager->allowsInteraction()) {
QWindowList done;
QWindowList list = QGuiApplication::topLevelWindows();
bool cancelled = false;
@@ -2667,17 +2805,17 @@ void QGuiApplicationPrivate::commitData(QSessionManager& manager)
}
}
if (cancelled)
- manager.cancel();
+ session_manager->cancel();
}
is_saving_session = false;
}
-void QGuiApplicationPrivate::saveState(QSessionManager &manager)
+void QGuiApplicationPrivate::saveState()
{
Q_Q(QGuiApplication);
is_saving_session = true;
- emit q->saveStateRequest(manager);
+ emit q->saveStateRequest(*session_manager);
is_saving_session = false;
}
#endif //QT_NO_SESSIONMANAGER
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index 0e9d6f2336..a0aef83eed 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -142,6 +142,8 @@ public:
static void setQuitOnLastWindowClosed(bool quit);
static bool quitOnLastWindowClosed();
+ static Qt::ApplicationState applicationState();
+
static int exec();
bool notify(QObject *, QEvent *);
@@ -159,6 +161,7 @@ Q_SIGNALS:
void lastWindowClosed();
void focusObjectChanged(QObject *focusObject);
void focusWindowChanged(QWindow *focusWindow);
+ void applicationStateChanged(Qt::ApplicationState state);
#ifndef QT_NO_SESSIONMANAGER
void commitDataRequest(QSessionManager &sessionManager);
void saveStateRequest(QSessionManager &sessionManager);
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 3a4b692b69..7a4a161476 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -130,8 +130,6 @@ public:
static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e);
static void processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e);
- static void processApplicationStateChangedEvent(QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e);
-
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
static void updateFilteredScreenOrientation(QScreen *screen);
@@ -236,12 +234,10 @@ public:
#ifndef QT_NO_SESSIONMANAGER
QSessionManager *session_manager;
- QString session_id;
- QString session_key;
bool is_session_restored;
bool is_saving_session;
- void commitData(QSessionManager& sm);
- void saveState(QSessionManager& sm);
+ void commitData();
+ void saveState();
#endif
struct ActiveTouchPointsKey {
@@ -275,6 +271,10 @@ public:
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
+ static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
+
+ static void setApplicationState(Qt::ApplicationState state);
+
protected:
virtual void notifyThemeChanged();
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index af3a46c675..c577831208 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -637,181 +637,17 @@ static const struct {
{ Qt::Key_Hangul_PostHanja,QT_TRANSLATE_NOOP("QShortcut", "Hangul PostHanja") },
{ Qt::Key_Hangul_Special, QT_TRANSLATE_NOOP("QShortcut", "Hangul Special") },
- { 0, 0 }
-};
-
-// Table of key bindings. It must be sorted on key sequence:
-// The integer value of VK_KEY | Modifier Keys (e.g., VK_META, and etc.)
-// A priority of 1 indicates that this is the primary key binding when multiple are defined.
-
-enum KeyPlatform {
- KB_Win = (1 << QPlatformTheme::WindowsKeyboardScheme),
- KB_Mac = (1 << QPlatformTheme::MacKeyboardScheme),
- KB_X11 = (1 << QPlatformTheme::X11KeyboardScheme),
- KB_KDE = (1 << QPlatformTheme::KdeKeyboardScheme),
- KB_Gnome = (1 << QPlatformTheme::GnomeKeyboardScheme),
- KB_CDE = (1 << QPlatformTheme::CdeKeyboardScheme),
- KB_All = 0xffff
-};
+ // --------------------------------------------------------------
+ // Miscellaneous keys
+ { Qt::Key_Cancel, QT_TRANSLATE_NOOP("QShortcut", "Cancel") },
+ { Qt::Key_Printer, QT_TRANSLATE_NOOP("QShortcut", "Printer") },
+ { Qt::Key_Execute, QT_TRANSLATE_NOOP("QShortcut", "Execute") },
+ { Qt::Key_Play, QT_TRANSLATE_NOOP("QShortcut", "Play") },
+ { Qt::Key_Zoom, QT_TRANSLATE_NOOP("QShortcut", "Zoom") },
-const QKeyBinding QKeySequencePrivate::keyBindings[] = {
-// StandardKey Priority Key Sequence Platforms
- {QKeySequence::Back, 0, Qt::Key_Backspace, KB_Win},
- {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Return, KB_All},
- {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Enter, KB_All},
- {QKeySequence::Delete, 1, Qt::Key_Delete, KB_All},
- {QKeySequence::MoveToStartOfLine, 0, Qt::Key_Home, KB_Win | KB_X11},
- {QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, KB_Mac},
- {QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, KB_Win | KB_X11},
- {QKeySequence::MoveToEndOfDocument, 0, Qt::Key_End, KB_Mac},
- {QKeySequence::MoveToPreviousChar, 0, Qt::Key_Left, KB_All},
- {QKeySequence::MoveToPreviousLine, 0, Qt::Key_Up, KB_All},
- {QKeySequence::MoveToNextChar, 0, Qt::Key_Right, KB_All},
- {QKeySequence::MoveToNextLine, 0, Qt::Key_Down, KB_All},
- {QKeySequence::MoveToPreviousPage, 1, Qt::Key_PageUp, KB_All},
- {QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, KB_All},
- {QKeySequence::HelpContents, 0, Qt::Key_F1, KB_Win | KB_X11},
- {QKeySequence::FindNext, 0, Qt::Key_F3, KB_X11},
- {QKeySequence::FindNext, 1, Qt::Key_F3, KB_Win},
- {QKeySequence::Refresh, 0, Qt::Key_F5, KB_Win | KB_X11},
- {QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
- {QKeySequence::Undo, 0, Qt::Key_F14, KB_X11}, //Undo on sun keyboards
- {QKeySequence::Copy, 0, Qt::Key_F16, KB_X11}, //Copy on sun keyboards
- {QKeySequence::Paste, 0, Qt::Key_F18, KB_X11}, //Paste on sun keyboards
- {QKeySequence::Cut, 0, Qt::Key_F20, KB_X11}, //Cut on sun keyboards
- {QKeySequence::PreviousChild, 0, Qt::Key_Back, KB_All},
- {QKeySequence::NextChild, 0, Qt::Key_Forward, KB_All},
- {QKeySequence::Forward, 0, Qt::SHIFT | Qt::Key_Backspace, KB_Win},
- {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, KB_All},
- {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, KB_All},
- {QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, KB_Win | KB_X11},
- {QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, KB_Win | KB_X11}, //## Check if this should work on mac
- {QKeySequence::SelectStartOfLine, 0, Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
- {QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, KB_Mac},
- {QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
- {QKeySequence::SelectEndOfDocument, 0, Qt::SHIFT | Qt::Key_End, KB_Mac},
- {QKeySequence::SelectPreviousChar, 0, Qt::SHIFT | Qt::Key_Left, KB_All},
- {QKeySequence::SelectPreviousLine, 0, Qt::SHIFT | Qt::Key_Up, KB_All},
- {QKeySequence::SelectNextChar, 0, Qt::SHIFT | Qt::Key_Right, KB_All},
- {QKeySequence::SelectNextLine, 0, Qt::SHIFT | Qt::Key_Down, KB_All},
- {QKeySequence::SelectPreviousPage, 0, Qt::SHIFT | Qt::Key_PageUp, KB_All},
- {QKeySequence::SelectNextPage, 0, Qt::SHIFT | Qt::Key_PageDown, KB_All},
- {QKeySequence::WhatsThis, 1, Qt::SHIFT | Qt::Key_F1, KB_All},
- {QKeySequence::FindPrevious, 0, Qt::SHIFT | Qt::Key_F3, KB_X11},
- {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, KB_Win},
- {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, KB_All},
- {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, KB_KDE},
- {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac},
- {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, KB_All},
- {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, KB_KDE},
- {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, KB_Mac},
- {QKeySequence::SelectAll, 1, Qt::CTRL | Qt::Key_A, KB_All},
- {QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, KB_All},
- {QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, KB_All},
- {QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, KB_X11}, //emacs (line edit only)
- {QKeySequence::Find, 0, Qt::CTRL | Qt::Key_F, KB_All},
- {QKeySequence::FindNext, 1, Qt::CTRL | Qt::Key_G, KB_Gnome | KB_Mac},
- {QKeySequence::FindNext, 0, Qt::CTRL | Qt::Key_G, KB_Win},
- {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Win},
- {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Gnome},
- {QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, KB_All},
- {QKeySequence::DeleteEndOfLine, 0, Qt::CTRL | Qt::Key_K, KB_X11}, //emacs (line edit only)
- {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, KB_All},
- {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, KB_All},
- {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, KB_All},
- {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_Gnome | KB_KDE | KB_Mac},
- {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, KB_Gnome | KB_Mac},
- {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, KB_KDE},
- {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, KB_All},
- {QKeySequence::AddTab, 0, Qt::CTRL | Qt::Key_T, KB_All},
- {QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, KB_All},
- {QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, KB_All},
- {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, KB_Win | KB_X11},
- {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, KB_Mac},
- {QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, KB_All},
- {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, KB_Win},
- {QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, KB_All},
- {QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, KB_Mac},
- {QKeySequence::Forward, 1, Qt::CTRL | Qt::Key_BracketRight, KB_Mac},
- {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::Key_BraceLeft, KB_Mac},
- {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_BraceRight, KB_Mac},
- {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_Tab, KB_Win | KB_X11},
- {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Tab, KB_Mac}, //different priority from above
- {QKeySequence::DeleteStartOfWord, 0, Qt::CTRL | Qt::Key_Backspace, KB_X11 | KB_Win},
- {QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, KB_X11 | KB_Win},
- {QKeySequence::DeleteEndOfWord, 0, Qt::CTRL | Qt::Key_Delete, KB_X11 | KB_Win},
- {QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, KB_Win | KB_X11},
- {QKeySequence::MoveToEndOfDocument, 0, Qt::CTRL | Qt::Key_End, KB_Win | KB_X11},
- {QKeySequence::Back, 0, Qt::CTRL | Qt::Key_Left, KB_Mac},
- {QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, KB_Win | KB_X11},
- {QKeySequence::MoveToStartOfLine, 0, Qt::CTRL | Qt::Key_Left, KB_Mac },
- {QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, KB_Mac},
- {QKeySequence::Forward, 0, Qt::CTRL | Qt::Key_Right, KB_Mac},
- {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL | Qt::Key_Right, KB_Mac },
- {QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, KB_Win | KB_X11},
- {QKeySequence::MoveToEndOfDocument, 1, Qt::CTRL | Qt::Key_Down, KB_Mac},
- {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_F4, KB_Win},
- {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_F4, KB_Mac},
- {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_F6, KB_Win},
- {QKeySequence::FullScreen, 1, Qt::CTRL | Qt::Key_F11, KB_Gnome},
- {QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11},
- {QKeySequence::FullScreen, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F, KB_KDE},
- {QKeySequence::FindPrevious, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Gnome | KB_Mac},
- {QKeySequence::FindPrevious, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Win},
- {QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, KB_KDE},
- {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac},
- {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Win | KB_X11},
- {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Mac},
- {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Win | KB_X11},
- {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Mac },//different priority from above
- {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, KB_X11},
- {QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
- {QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
- {QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Win | KB_X11},
- {QKeySequence::SelectStartOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Mac },
- {QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, KB_Mac},
- {QKeySequence::SelectNextWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Win | KB_X11},
- {QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Mac },
- {QKeySequence::SelectEndOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Down, KB_Mac},
- {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F6, KB_Win},
- {QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, KB_Win},
- {QKeySequence::DeleteStartOfWord, 0, Qt::ALT | Qt::Key_Backspace, KB_Mac},
- {QKeySequence::FullScreen, 0, Qt::ALT | Qt::Key_Enter, KB_Win},
- {QKeySequence::DeleteEndOfWord, 0, Qt::ALT | Qt::Key_Delete, KB_Mac},
- {QKeySequence::Back, 1, Qt::ALT | Qt::Key_Left, KB_Win | KB_X11},
- {QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, KB_Mac},
- {QKeySequence::MoveToStartOfBlock, 0, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only
- {QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, KB_Mac},
- {QKeySequence::Forward, 1, Qt::ALT | Qt::Key_Right, KB_Win | KB_X11},
- {QKeySequence::MoveToEndOfBlock, 0, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only
- {QKeySequence::MoveToPreviousPage, 0, Qt::ALT | Qt::Key_PageUp, KB_Mac },
- {QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, KB_Mac },
- {QKeySequence::Redo, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Backspace,KB_Win},
- {QKeySequence::SelectPreviousWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Left, KB_Mac},
- {QKeySequence::SelectStartOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only
- {QKeySequence::SelectNextWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Right, KB_Mac},
- {QKeySequence::SelectEndOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only
- {QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, KB_Mac},
- {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac},
- {QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, KB_Mac},
- {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, KB_Mac},
- {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Enter, KB_Mac},
- {QKeySequence::MoveToStartOfLine, 0, Qt::META | Qt::Key_Left, KB_Mac},
- {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_Up, KB_Mac},
- {QKeySequence::MoveToEndOfLine, 0, Qt::META | Qt::Key_Right, KB_Mac},
- {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, KB_Mac},
- {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, KB_Mac},
- {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, KB_Mac},
- {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, KB_Mac},
- {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, KB_Mac},
- {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, KB_Mac},
- {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, KB_Mac},
- {QKeySequence::FullScreen, 1, Qt::META | Qt::CTRL | Qt::Key_F, KB_Mac}
+ { 0, 0 }
};
-const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate::keyBindings)/(sizeof(QKeyBinding));
-
-
/*!
\enum QKeySequence::StandardKey
\since 4.2
@@ -975,21 +811,6 @@ QKeySequence::QKeySequence(const QKeySequence& keysequence)
d->ref.ref();
}
-#if defined(Q_OS_MACX)
-static inline int maybeSwapShortcut(int shortcut)
-{
- if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
- uint oldshortcut = shortcut;
- shortcut &= ~(Qt::CTRL | Qt::META);
- if (oldshortcut & Qt::CTRL)
- shortcut |= Qt::META;
- if (oldshortcut & Qt::META)
- shortcut |= Qt::CTRL;
- }
- return shortcut;
-}
-#endif
-
/*!
\since 4.2
@@ -1001,24 +822,7 @@ static inline int maybeSwapShortcut(int shortcut)
*/
QList<QKeySequence> QKeySequence::keyBindings(StandardKey key)
{
- const uint platform = QKeySequencePrivate::currentKeyPlatforms();
- QList <QKeySequence> list;
- for (uint i = 0; i < QKeySequencePrivate::numberOfKeyBindings ; ++i) {
- QKeyBinding keyBinding = QKeySequencePrivate::keyBindings[i];
- if (keyBinding.standardKey == key && (keyBinding.platform & platform)) {
- uint shortcut =
-#if defined(Q_OS_MACX)
- maybeSwapShortcut(QKeySequencePrivate::keyBindings[i].shortcut);
-#else
- QKeySequencePrivate::keyBindings[i].shortcut;
-#endif
- if (keyBinding.priority > 0)
- list.prepend(QKeySequence(shortcut));
- else
- list.append(QKeySequence(shortcut));
- }
- }
- return list;
+ return QGuiApplicationPrivate::platformTheme()->keyBindings(key);
}
/*!
@@ -1343,19 +1147,6 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
return ret;
}
-unsigned QKeySequencePrivate::currentKeyPlatforms()
-{
- int keyboardScheme = QPlatformTheme::WindowsKeyboardScheme;
- if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
- keyboardScheme = theme->themeHint(QPlatformTheme::KeyboardScheme).toInt();
- unsigned result = 1u << keyboardScheme;
- if (keyboardScheme == QPlatformTheme::KdeKeyboardScheme
- || keyboardScheme == QPlatformTheme::GnomeKeyboardScheme
- || keyboardScheme == QPlatformTheme::CdeKeyboardScheme)
- result |= KB_X11;
- return result;
-}
-
/*!
Creates a shortcut string for \a key. For example,
Qt::CTRL+Qt::Key_O gives "Ctrl+O". The strings, "Ctrl", "Shift", etc. are
diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h
index 05460c6651..8a989682d8 100644
--- a/src/gui/kernel/qkeysequence.h
+++ b/src/gui/kernel/qkeysequence.h
@@ -44,6 +44,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qstring.h>
+#include <QtCore/qobjectdefs.h>
QT_BEGIN_NAMESPACE
@@ -68,6 +69,9 @@ class QKeySequencePrivate;
class Q_GUI_EXPORT QKeySequence
{
+ Q_GADGET
+ Q_ENUMS(StandardKey)
+
public:
enum StandardKey {
UnknownKey,
diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h
index e28a7e526c..eac0d4b0a6 100644
--- a/src/gui/kernel/qkeysequence_p.h
+++ b/src/gui/kernel/qkeysequence_p.h
@@ -84,11 +84,6 @@ public:
int key[4];
static QString encodeString(int key, QKeySequence::SequenceFormat format);
static int decodeString(const QString &keyStr, QKeySequence::SequenceFormat format);
-
- static const QKeyBinding keyBindings[];
- static const uint numberOfKeyBindings;
-
- static unsigned currentKeyPlatforms();
};
#endif // QT_NO_SHORTCUT
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 5f86b511f7..f297236655 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -48,6 +48,8 @@
#include <QtCore/QUrl>
#include <QtGui/QColor>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
/*!
@@ -60,18 +62,6 @@ QT_BEGIN_NAMESPACE
*/
-/*!
- \enum QPlatformDialogHelper::StyleHint
-
- This enum type specifies platform-specific style hints.
-
- \value SnapToDefaultButton Snap the mouse to the center of the default
- button. There is corresponding system
- setting on Windows.
-
- \sa styleHint()
-*/
-
QPlatformDialogHelper::QPlatformDialogHelper()
{
}
@@ -87,10 +77,7 @@ QVariant QPlatformDialogHelper::styleHint(StyleHint hint) const
QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHint hint)
{
- switch (hint) {
- case QPlatformDialogHelper::SnapToDefaultButton:
- return QVariant(false);
- }
+ Q_UNUSED(hint);
return QVariant();
}
@@ -198,7 +185,7 @@ QColorDialogStaticData::QColorDialogStaticData() : customSet(false)
for (int r = 0; r < 4; ++r)
for (int b = 0; b < 3; ++b)
standardRgb[i++] = qRgb(r * 255 / 3, g * 255 / 3, b * 255 / 2);
- qFill(customRgb, customRgb + CustomColorCount, 0xffffffff);
+ std::fill(customRgb, customRgb + CustomColorCount, 0xffffffff);
readSettings();
}
@@ -374,11 +361,12 @@ public:
QDir::Filters filters;
QList<QUrl> sidebarUrls;
QStringList nameFilters;
+ QStringList mimeTypeFilters;
QString defaultSuffix;
QStringList history;
- QString initialDirectory;
+ QUrl initialDirectory;
QString initiallySelectedNameFilter;
- QStringList initiallySelectedFiles;
+ QList<QUrl> initiallySelectedFiles;
};
QFileDialogOptions::QFileDialogOptions() : d(new QFileDialogOptionsPrivate)
@@ -492,9 +480,21 @@ QStringList QFileDialogOptions::nameFilters() const
return d->nameFilters;
}
+void QFileDialogOptions::setMimeTypeFilters(const QStringList &filters)
+{
+ d->mimeTypeFilters = filters;
+}
+
+QStringList QFileDialogOptions::mimeTypeFilters() const
+{
+ return d->mimeTypeFilters;
+}
+
void QFileDialogOptions::setDefaultSuffix(const QString &suffix)
{
d->defaultSuffix = suffix;
+ if (d->defaultSuffix.size() > 1 && d->defaultSuffix.startsWith(QLatin1Char('.')))
+ d->defaultSuffix.remove(0, 1); // Silently change ".txt" -> "txt".
}
QString QFileDialogOptions::defaultSuffix() const
@@ -528,12 +528,12 @@ bool QFileDialogOptions::isLabelExplicitlySet(DialogLabel label)
return label >= 0 && label < DialogLabelCount && !d->labels[label].isEmpty();
}
-QString QFileDialogOptions::initialDirectory() const
+QUrl QFileDialogOptions::initialDirectory() const
{
return d->initialDirectory;
}
-void QFileDialogOptions::setInitialDirectory(const QString &directory)
+void QFileDialogOptions::setInitialDirectory(const QUrl &directory)
{
d->initialDirectory = directory;
}
@@ -548,16 +548,21 @@ void QFileDialogOptions::setInitiallySelectedNameFilter(const QString &filter)
d->initiallySelectedNameFilter = filter;
}
-QStringList QFileDialogOptions::initiallySelectedFiles() const
+QList<QUrl> QFileDialogOptions::initiallySelectedFiles() const
{
return d->initiallySelectedFiles;
}
-void QFileDialogOptions::setInitiallySelectedFiles(const QStringList &files)
+void QFileDialogOptions::setInitiallySelectedFiles(const QList<QUrl> &files)
{
d->initiallySelectedFiles = files;
}
+bool QPlatformFileDialogHelper::isSupportedUrl(const QUrl &url) const
+{
+ return url.isLocalFile();
+}
+
/*!
\class QPlatformFileDialogHelper
\since 5.0
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index ecc00ed8c6..5269416ffd 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -57,6 +57,7 @@
#include <QtCore/QSharedDataPointer>
#include <QtCore/QSharedPointer>
#include <QtCore/QDir>
+#include <QtCore/QUrl>
#include <QtGui/QRgb>
QT_BEGIN_NAMESPACE
@@ -77,7 +78,6 @@ class Q_GUI_EXPORT QPlatformDialogHelper : public QObject
Q_OBJECT
public:
enum StyleHint {
- SnapToDefaultButton
};
enum DialogCode { Rejected, Accepted };
@@ -163,7 +163,11 @@ class Q_GUI_EXPORT QFontDialogOptions
public:
enum FontDialogOption {
NoButtons = 0x00000001,
- DontUseNativeDialog = 0x00000002
+ DontUseNativeDialog = 0x00000002,
+ ScalableFonts = 0x00000004,
+ NonScalableFonts = 0x00000008,
+ MonospacedFonts = 0x00000010,
+ ProportionalFonts = 0x00000020
};
Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
@@ -217,13 +221,14 @@ public:
enum FileDialogOption
{
- ShowDirsOnly = 0x00000001,
- DontResolveSymlinks = 0x00000002,
- DontConfirmOverwrite = 0x00000004,
- DontUseSheet = 0x00000008,
- DontUseNativeDialog = 0x00000010,
- ReadOnly = 0x00000020,
- HideNameFilterDetails = 0x00000040
+ ShowDirsOnly = 0x00000001,
+ DontResolveSymlinks = 0x00000002,
+ DontConfirmOverwrite = 0x00000004,
+ DontUseSheet = 0x00000008,
+ DontUseNativeDialog = 0x00000010,
+ ReadOnly = 0x00000020,
+ HideNameFilterDetails = 0x00000040,
+ DontUseCustomDirectoryIcons = 0x00000080
};
Q_DECLARE_FLAGS(FileDialogOptions, FileDialogOption)
@@ -260,6 +265,9 @@ public:
void setNameFilters(const QStringList &filters);
QStringList nameFilters() const;
+ void setMimeTypeFilters(const QStringList &filters);
+ QStringList mimeTypeFilters() const;
+
void setDefaultSuffix(const QString &suffix);
QString defaultSuffix() const;
@@ -270,14 +278,14 @@ public:
QString labelText(DialogLabel label) const;
bool isLabelExplicitlySet(DialogLabel label);
- QString initialDirectory() const;
- void setInitialDirectory(const QString &);
+ QUrl initialDirectory() const;
+ void setInitialDirectory(const QUrl &);
QString initiallySelectedNameFilter() const;
void setInitiallySelectedNameFilter(const QString &);
- QStringList initiallySelectedFiles() const;
- void setInitiallySelectedFiles(const QStringList &);
+ QList<QUrl> initiallySelectedFiles() const;
+ void setInitiallySelectedFiles(const QList<QUrl> &);
private:
QSharedDataPointer<QFileDialogOptionsPrivate> d;
@@ -290,14 +298,16 @@ class Q_GUI_EXPORT QPlatformFileDialogHelper : public QPlatformDialogHelper
Q_OBJECT
public:
virtual bool defaultNameFilterDisables() const = 0;
- virtual void setDirectory(const QString &directory) = 0;
- virtual QString directory() const = 0;
- virtual void selectFile(const QString &filename) = 0;
- virtual QStringList selectedFiles() const = 0;
+ virtual void setDirectory(const QUrl &directory) = 0;
+ virtual QUrl directory() const = 0;
+ virtual void selectFile(const QUrl &filename) = 0;
+ virtual QList<QUrl> selectedFiles() const = 0;
virtual void setFilter() = 0;
virtual void selectNameFilter(const QString &filter) = 0;
virtual QString selectedNameFilter() const = 0;
+ virtual bool isSupportedUrl(const QUrl &url) const;
+
const QSharedPointer<QFileDialogOptions> &options() const;
void setOptions(const QSharedPointer<QFileDialogOptions> &options);
@@ -305,10 +315,10 @@ public:
static const char *filterRegExp;
Q_SIGNALS:
- void fileSelected(const QString &file);
- void filesSelected(const QStringList &files);
- void currentChanged(const QString &path);
- void directoryEntered(const QString &directory);
+ void fileSelected(const QUrl &file);
+ void filesSelected(const QList<QUrl> &files);
+ void currentChanged(const QUrl &path);
+ void directoryEntered(const QUrl &directory);
void filterSelected(const QString &filter);
private:
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index e4f45ebb6e..06d2aa4fca 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -51,6 +51,10 @@
#include <private/qdnd_p.h>
#include <private/qsimpledrag_p.h>
+#ifndef QT_NO_SESSIONMANAGER
+# include <qpa/qplatformsessionmanager.h>
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -237,7 +241,7 @@ QPlatformServices *QPlatformIntegration::services() const
bool QPlatformIntegration::hasCapability(Capability cap) const
{
- return cap == NonFullScreenWindows;
+ return cap == NonFullScreenWindows || cap == NativeWidgets;
}
QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
@@ -328,6 +332,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return QVariant(false);
case SynthesizeMouseFromTouchEvents:
return true;
+ case SetFocusOnTouchRelease:
+ return QVariant(false);
}
return 0;
@@ -393,4 +399,17 @@ QPlatformOffscreenSurface *QPlatformIntegration::createPlatformOffscreenSurface(
return 0;
}
+#ifndef QT_NO_SESSIONMANAGER
+/*!
+ \since 5.2
+
+ Factory function for QPlatformSessionManager. The default QPlatformSessionManager provides the same
+ functionality as the QSessionManager.
+*/
+QPlatformSessionManager *QPlatformIntegration::createPlatformSessionManager(const QString &id, const QString &key) const
+{
+ return new QPlatformSessionManager(id, key);
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index b7a44b13de..a98d332356 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -74,6 +74,7 @@ class QPlatformTheme;
class QPlatformDialogHelper;
class QPlatformSharedGraphicsCache;
class QPlatformServices;
+class QPlatformSessionManager;
class QKeyEvent;
class QPlatformOffscreenSurface;
class QOffscreenSurface;
@@ -91,7 +92,8 @@ public:
MultipleWindows,
ApplicationState,
ForeignWindows,
- NonFullScreenWindows
+ NonFullScreenWindows,
+ NativeWidgets
};
virtual ~QPlatformIntegration() { }
@@ -141,7 +143,8 @@ public:
StartDragVelocity,
UseRtlExtensions,
SynthesizeMouseFromTouchEvents,
- PasswordMaskCharacter
+ PasswordMaskCharacter,
+ SetFocusOnTouchRelease
};
virtual QVariant styleHint(StyleHint hint) const;
@@ -154,6 +157,9 @@ public:
virtual QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
+#ifndef QT_NO_SESSIONMANAGER
+ virtual QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const;
+#endif
protected:
void screenAdded(QPlatformScreen *screen);
};
diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp
index 21f53d17de..365edd2010 100644
--- a/src/gui/kernel/qplatformintegrationfactory.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory.cpp
@@ -55,18 +55,30 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QPlatformIntegrationFactoryInterface_iid, QLatin1String("/platforms"), Qt::CaseInsensitive))
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
(QPlatformIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
-#endif
-QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platform, const QStringList &paramList, const QString &platformPluginPath)
+static inline QPlatformIntegration *loadIntegration(QFactoryLoader *loader, const QString &key, const QStringList &parameters, int &argc, char ** argv)
+{
+ const int index = loader->indexOf(key);
+ if (index != -1) {
+ if (QPlatformIntegrationPlugin *factory = qobject_cast<QPlatformIntegrationPlugin *>(loader->instance(index)))
+ if (QPlatformIntegration *result = factory->create(key, parameters, argc, argv))
+ return result;
+ }
+ return 0;
+}
+
+#endif // !QT_NO_LIBRARY
+
+QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platform, const QStringList &paramList, int &argc, char **argv, const QString &platformPluginPath)
{
#ifndef QT_NO_LIBRARY
// Try loading the plugin from platformPluginPath first:
if (!platformPluginPath.isEmpty()) {
QCoreApplication::addLibraryPath(platformPluginPath);
- if (QPlatformIntegration *ret = qLoadPlugin1<QPlatformIntegration, QPlatformIntegrationPlugin>(directLoader(), platform, paramList))
+ if (QPlatformIntegration *ret = loadIntegration(directLoader(), platform, paramList, argc, argv))
return ret;
}
- if (QPlatformIntegration *ret = qLoadPlugin1<QPlatformIntegration, QPlatformIntegrationPlugin>(loader(), platform, paramList))
+ if (QPlatformIntegration *ret = loadIntegration(loader(), platform, paramList, argc, argv))
return ret;
#endif
return 0;
diff --git a/src/gui/kernel/qplatformintegrationfactory_p.h b/src/gui/kernel/qplatformintegrationfactory_p.h
index fb3ba55316..bc8ce11609 100644
--- a/src/gui/kernel/qplatformintegrationfactory_p.h
+++ b/src/gui/kernel/qplatformintegrationfactory_p.h
@@ -64,7 +64,7 @@ class Q_GUI_EXPORT QPlatformIntegrationFactory
{
public:
static QStringList keys(const QString &platformPluginPath = QString());
- static QPlatformIntegration *create(const QString &name, const QStringList &args, const QString &platformPluginPath = QString());
+ static QPlatformIntegration *create(const QString &name, const QStringList &args, int &argc, char **argv, const QString &platformPluginPath = QString());
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationplugin.cpp b/src/gui/kernel/qplatformintegrationplugin.cpp
index 0f7f365d2a..2a9a047141 100644
--- a/src/gui/kernel/qplatformintegrationplugin.cpp
+++ b/src/gui/kernel/qplatformintegrationplugin.cpp
@@ -52,4 +52,18 @@ QPlatformIntegrationPlugin::~QPlatformIntegrationPlugin()
{
}
+QPlatformIntegration *QPlatformIntegrationPlugin::create(const QString &key, const QStringList &paramList)
+{
+ Q_UNUSED(key)
+ Q_UNUSED(paramList);
+ return 0;
+}
+
+QPlatformIntegration *QPlatformIntegrationPlugin::create(const QString &key, const QStringList &paramList, int &argc, char **argv)
+{
+ Q_UNUSED(argc)
+ Q_UNUSED(argv)
+ return create(key, paramList); // Fallback for platform plugins that do not implement the argc/argv version.
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationplugin.h b/src/gui/kernel/qplatformintegrationplugin.h
index 434366f0b0..e624e2d31d 100644
--- a/src/gui/kernel/qplatformintegrationplugin.h
+++ b/src/gui/kernel/qplatformintegrationplugin.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QPlatformIntegration;
-#define QPlatformIntegrationFactoryInterface_iid "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1"
+#define QPlatformIntegrationFactoryInterface_iid "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2"
class Q_GUI_EXPORT QPlatformIntegrationPlugin : public QObject
{
@@ -68,7 +68,8 @@ public:
explicit QPlatformIntegrationPlugin(QObject *parent = 0);
~QPlatformIntegrationPlugin();
- virtual QPlatformIntegration *create(const QString &key, const QStringList &paramList) = 0;
+ virtual QPlatformIntegration *create(const QString &key, const QStringList &paramList);
+ virtual QPlatformIntegration *create(const QString &key, const QStringList &paramList, int &argc, char **argv);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformservices.cpp b/src/gui/kernel/qplatformservices.cpp
index f2cade0a35..d09b74c6fe 100644
--- a/src/gui/kernel/qplatformservices.cpp
+++ b/src/gui/kernel/qplatformservices.cpp
@@ -74,7 +74,10 @@ bool QPlatformServices::openDocument(const QUrl &url)
/*!
* \brief QPlatformServices::desktopEnvironment returns the active desktop environment.
*
- * On Unix this function returns KDE, GNOME or UNKNOWN.
+ * On Unix this function returns the uppercase desktop environment name, such as
+ * KDE, GNOME, UNITY, XFCE, LXDE etc. or UNKNOWN if none was detected.
+ * The primary way to detect the desktop environment is the environment variable
+ * XDG_CURRENT_DESKTOP.
*/
QByteArray QPlatformServices::desktopEnvironment() const
{
diff --git a/src/plugins/platforms/kms/qkmsudevlistener.cpp b/src/gui/kernel/qplatformsessionmanager.cpp
index b2fb110479..6eb88a9450 100644
--- a/src/plugins/platforms/kms/qkmsudevlistener.cpp
+++ b/src/gui/kernel/qplatformsessionmanager.cpp
@@ -1,9 +1,10 @@
/****************************************************************************
**
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,63 +40,92 @@
**
****************************************************************************/
-#include <qkmsudevlistener.h>
+#include "qplatformsessionmanager.h"
QT_BEGIN_NAMESPACE
-QKmsUdevListener::QKmsUdevListener(QObject *parent)
- : QObject(parent)
+QPlatformSessionManager::QPlatformSessionManager(const QString &id, const QString &key)
+ : m_sessionId(id),
+ m_sessionKey(key),
+ m_restartHint(QSessionManager::RestartIfRunning)
{
- m_udev = udev_new();
}
-QKmsUdevListener::~QKmsUdevListener()
+QPlatformSessionManager::~QPlatformSessionManager()
{
- udev_unref(m_udev);
}
-void QKmsUdevListener::addHandler(QKmsUdevHandler *handler)
+QString QPlatformSessionManager::sessionId() const
{
- m_handlers.removeAll((QKmsUdevHandler *) 0);
- m_handlers.removeAll(handler);
- m_handlers.prepend(handler);
-
- scan();
+ return m_sessionId;
}
-bool QKmsUdevListener::create(struct udev_device *device)
+QString QPlatformSessionManager::sessionKey() const
{
- foreach (QKmsUdevHandler *handler, m_handlers) {
- if (!handler)
- continue;
+ return m_sessionKey;
+}
- QObject *obj = handler->create(device);
- if (obj) {
- m_devices[udev_device_get_syspath(device)] = obj;
- return true;
- }
- }
+bool QPlatformSessionManager::allowsInteraction()
+{
+ return false;
+}
+bool QPlatformSessionManager::allowsErrorInteraction()
+{
return false;
}
-void QKmsUdevListener::scan()
+void QPlatformSessionManager::release()
+{
+}
+
+void QPlatformSessionManager::cancel()
{
- struct udev_enumerate *e;
- struct udev_list_entry *entry;
+}
- e = udev_enumerate_new(m_udev);
- udev_enumerate_scan_devices(e);
- udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
- const char *path = udev_list_entry_get_name(entry);
- if (m_devices.contains(path))
- continue;
+void QPlatformSessionManager::setRestartHint(QSessionManager::RestartHint restartHint)
+{
+ m_restartHint = restartHint;
+}
+
+QSessionManager::RestartHint QPlatformSessionManager::restartHint() const
+{
+ return m_restartHint;
+}
+
+void QPlatformSessionManager::setRestartCommand(const QStringList &command)
+{
+ m_restartCommand = command;
+}
- struct udev_device *device = udev_device_new_from_syspath(m_udev, path);
- create(device);
- udev_device_unref(device);
- }
- udev_enumerate_unref(e);
+QStringList QPlatformSessionManager::restartCommand() const
+{
+ return m_restartCommand;
+}
+
+void QPlatformSessionManager::setDiscardCommand(const QStringList &command)
+{
+ m_discardCommand = command;
+}
+
+QStringList QPlatformSessionManager::discardCommand() const
+{
+ return m_discardCommand;
+}
+
+void QPlatformSessionManager::setManagerProperty(const QString &name, const QStringList &value)
+{
+ Q_UNUSED(name)
+ Q_UNUSED(value)
+}
+
+bool QPlatformSessionManager::isPhase2() const
+{
+ return false;
+}
+
+void QPlatformSessionManager::requestPhase2()
+{
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h b/src/gui/kernel/qplatformsessionmanager.h
index 1686983bd7..0389a7b076 100644
--- a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h
+++ b/src/gui/kernel/qplatformsessionmanager.h
@@ -1,9 +1,10 @@
/****************************************************************************
**
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -38,59 +39,64 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QMALIITPLATFORMINPUTCONTEXT_H
-#define QMALIITPLATFORMINPUTCONTEXT_H
-#include <qpa/qplatforminputcontext.h>
-#include <QDBusArgument>
+#ifndef QPLATFORMSESSIONMANAGER_H
+#define QPLATFORMSESSIONMANAGER_H
-QT_BEGIN_NAMESPACE
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
+#include <QtCore/qmetatype.h>
+#include <QtCore/qnamespace.h>
+
+#include <QtGui/qsessionmanager.h>
-class QMaliitPlatformInputContextPrivate;
-class QDBusVariant;
-class QDBusMessage;
+QT_BEGIN_NAMESPACE
-class QMaliitPlatformInputContext : public QPlatformInputContext
+class Q_GUI_EXPORT QPlatformSessionManager
{
- Q_OBJECT
public:
- QMaliitPlatformInputContext();
- ~QMaliitPlatformInputContext();
-
- bool isValid() const;
-
- void invokeAction(QInputMethod::Action action, int x);
- void reset(void);
- void update(Qt::InputMethodQueries);
- virtual QRectF keyboardRect() const;
-
- virtual void showInputPanel();
- virtual void hideInputPanel();
- virtual bool isInputPanelVisible() const;
- void setFocusObject(QObject *object);
-
-public Q_SLOTS:
- void activationLostEvent();
- void commitString(const QString &in0, int in1, int in2, int in3);
- void updatePreedit(const QDBusMessage &message);
- void copy();
- void imInitiatedHide();
- void keyEvent(int type, int key, int modifiers, const QString &text, bool autoRepeat, int count, uchar requestType_);
- void paste();
- bool preeditRectangle(int &x, int &y, int &width, int &height);
- bool selection(QString &selection);
- void setDetectableAutoRepeat(bool in0);
- void setGlobalCorrectionEnabled(bool enable);
- void setLanguage(const QString &);
- void setRedirectKeys(bool );
- void setSelection(int start, int length);
- void updateInputMethodArea(int x, int y, int width, int height);
- void updateServerWindowOrientation(Qt::ScreenOrientation orientation);
+ explicit QPlatformSessionManager(const QString &id, const QString &key);
+ virtual ~QPlatformSessionManager();
+
+ virtual QString sessionId() const;
+ virtual QString sessionKey() const;
+
+ virtual bool allowsInteraction();
+ virtual bool allowsErrorInteraction();
+ virtual void release();
+
+ virtual void cancel();
+
+ virtual void setRestartHint(QSessionManager::RestartHint restartHint);
+ virtual QSessionManager::RestartHint restartHint() const;
+
+ virtual void setRestartCommand(const QStringList &command);
+ virtual QStringList restartCommand() const;
+ virtual void setDiscardCommand(const QStringList &command);
+ virtual QStringList discardCommand() const;
+
+ virtual void setManagerProperty(const QString &name, const QStringList &value);
+
+ virtual bool isPhase2() const;
+ virtual void requestPhase2();
private:
- QMaliitPlatformInputContextPrivate *d;
+ QStringList m_restartCommand;
+ QStringList m_discardCommand;
+ const QString m_sessionId;
+ const QString m_sessionKey;
+ QSessionManager::RestartHint m_restartHint;
+
+ Q_DISABLE_COPY(QPlatformSessionManager)
};
QT_END_NAMESPACE
-#endif
+#endif // QPLATFORMSESSIONMANAGER_H
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 02b69bcb4d..18ac9dc088 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -49,6 +49,8 @@
#include <qpalette.h>
#include <qtextformat.h>
#include <qiconloader_p.h>
+#include "private/qguiapplication_p.h"
+
QT_BEGIN_NAMESPACE
@@ -136,9 +138,184 @@ QT_BEGIN_NAMESPACE
\value TabAllWidgets (bool) Whether tab navigation should go through all the widgets or components,
or just through text boxes and list views. This is mostly a Mac feature.
+ \value DialogSnapToDefaultButton (bool) Whether the mouse should snap to the default button when a dialog
+ becomes visible.
+
\sa themeHint(), QStyle::pixelMetric()
*/
+
+// Table of key bindings. It must be sorted on key sequence:
+// The integer value of VK_KEY | Modifier Keys (e.g., VK_META, and etc.)
+// A priority of 1 indicates that this is the primary key binding when multiple are defined.
+
+enum KeyPlatform {
+ KB_Win = (1 << QPlatformTheme::WindowsKeyboardScheme),
+ KB_Mac = (1 << QPlatformTheme::MacKeyboardScheme),
+ KB_X11 = (1 << QPlatformTheme::X11KeyboardScheme),
+ KB_KDE = (1 << QPlatformTheme::KdeKeyboardScheme),
+ KB_Gnome = (1 << QPlatformTheme::GnomeKeyboardScheme),
+ KB_CDE = (1 << QPlatformTheme::CdeKeyboardScheme),
+ KB_All = 0xffff
+};
+
+const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
+ // StandardKey Priority Key Sequence Platforms
+ {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, KB_Mac},
+ {QKeySequence::HelpContents, 0, Qt::Key_F1, KB_Win | KB_X11},
+ {QKeySequence::WhatsThis, 1, Qt::SHIFT | Qt::Key_F1, KB_All},
+ {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, KB_All},
+ {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_F4, KB_Mac},
+ {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_F4, KB_Win},
+ {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, KB_Mac},
+ {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, KB_Win | KB_X11},
+ {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, KB_All},
+ {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, KB_All},
+ {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac},
+ {QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, KB_X11}, //emacs (line edit only)
+ {QKeySequence::Delete, 1, Qt::Key_Delete, KB_All},
+ {QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, KB_All},
+ {QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, KB_Win | KB_X11}, //## Check if this should work on mac
+ {QKeySequence::Cut, 0, Qt::Key_F20, KB_X11}, //Cut on sun keyboards
+ {QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, KB_X11 | KB_Win},
+ {QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, KB_All},
+ {QKeySequence::Copy, 0, Qt::Key_F16, KB_X11}, //Copy on sun keyboards
+ {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, KB_X11},
+ {QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, KB_All},
+ {QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, KB_Win | KB_X11},
+ {QKeySequence::Paste, 0, Qt::Key_F18, KB_X11}, //Paste on sun keyboards
+ {QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, KB_Win},
+ {QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, KB_All},
+ {QKeySequence::Undo, 0, Qt::Key_F14, KB_X11}, //Undo on sun keyboards
+ {QKeySequence::Redo, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Backspace,KB_Win},
+ {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Mac},
+ {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Win | KB_X11},
+ {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, KB_Win},
+ {QKeySequence::Back, 1, Qt::ALT | Qt::Key_Left, KB_Win | KB_X11},
+ {QKeySequence::Back, 0, Qt::CTRL | Qt::Key_Left, KB_Mac},
+ {QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, KB_Mac},
+ {QKeySequence::Back, 0, Qt::Key_Backspace, KB_Win},
+ {QKeySequence::Forward, 1, Qt::ALT | Qt::Key_Right, KB_Win | KB_X11},
+ {QKeySequence::Forward, 0, Qt::CTRL | Qt::Key_Right, KB_Mac},
+ {QKeySequence::Forward, 1, Qt::CTRL | Qt::Key_BracketRight, KB_Mac},
+ {QKeySequence::Forward, 0, Qt::SHIFT | Qt::Key_Backspace, KB_Win},
+ {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, KB_Gnome | KB_Mac},
+ {QKeySequence::Refresh, 0, Qt::Key_F5, KB_Win | KB_X11},
+ {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, KB_All},
+ {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, KB_All},
+ {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, KB_All},
+ {QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, KB_KDE},
+ {QKeySequence::AddTab, 0, Qt::CTRL | Qt::Key_T, KB_All},
+ {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_F6, KB_Win},
+ {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Tab, KB_Mac}, //different priority from above
+ {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_Tab, KB_Win | KB_X11},
+ {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_BraceRight, KB_Mac},
+ {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, KB_KDE},
+ {QKeySequence::NextChild, 0, Qt::Key_Forward, KB_All},
+ {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F6, KB_Win},
+ {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Mac },//different priority from above
+ {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Win | KB_X11},
+ {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::Key_BraceLeft, KB_Mac},
+ {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, KB_KDE},
+ {QKeySequence::PreviousChild, 0, Qt::Key_Back, KB_All},
+ {QKeySequence::Find, 0, Qt::CTRL | Qt::Key_F, KB_All},
+ {QKeySequence::FindNext, 0, Qt::CTRL | Qt::Key_G, KB_Win},
+ {QKeySequence::FindNext, 1, Qt::CTRL | Qt::Key_G, KB_Gnome | KB_Mac},
+ {QKeySequence::FindNext, 1, Qt::Key_F3, KB_Win},
+ {QKeySequence::FindNext, 0, Qt::Key_F3, KB_X11},
+ {QKeySequence::FindPrevious, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Win},
+ {QKeySequence::FindPrevious, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Gnome | KB_Mac},
+ {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, KB_Win},
+ {QKeySequence::FindPrevious, 0, Qt::SHIFT | Qt::Key_F3, KB_X11},
+ {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, KB_KDE},
+ {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Gnome},
+ {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Win},
+ {QKeySequence::SelectAll, 1, Qt::CTRL | Qt::Key_A, KB_All},
+ {QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, KB_All},
+ {QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, KB_All},
+ {QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, KB_All},
+ {QKeySequence::MoveToNextChar, 0, Qt::Key_Right, KB_All},
+ {QKeySequence::MoveToPreviousChar, 0, Qt::Key_Left, KB_All},
+ {QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, KB_Mac},
+ {QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, KB_Win | KB_X11},
+ {QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, KB_Mac},
+ {QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, KB_Win | KB_X11},
+ {QKeySequence::MoveToNextLine, 0, Qt::Key_Down, KB_All},
+ {QKeySequence::MoveToPreviousLine, 0, Qt::Key_Up, KB_All},
+ {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, KB_Mac},
+ {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, KB_Mac},
+ {QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, KB_Mac },
+ {QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, KB_All},
+ {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, KB_Mac},
+ {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_Up, KB_Mac},
+ {QKeySequence::MoveToPreviousPage, 0, Qt::ALT | Qt::Key_PageUp, KB_Mac },
+ {QKeySequence::MoveToPreviousPage, 1, Qt::Key_PageUp, KB_All},
+ {QKeySequence::MoveToStartOfLine, 0, Qt::META | Qt::Key_Left, KB_Mac},
+ {QKeySequence::MoveToStartOfLine, 0, Qt::CTRL | Qt::Key_Left, KB_Mac },
+ {QKeySequence::MoveToStartOfLine, 0, Qt::Key_Home, KB_Win | KB_X11},
+ {QKeySequence::MoveToEndOfLine, 0, Qt::META | Qt::Key_Right, KB_Mac},
+ {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL | Qt::Key_Right, KB_Mac },
+ {QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, KB_Win | KB_X11},
+ {QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, KB_Mac},
+ {QKeySequence::MoveToStartOfBlock, 0, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only
+ {QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, KB_Mac},
+ {QKeySequence::MoveToEndOfBlock, 0, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only
+ {QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, KB_Mac},
+ {QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, KB_Win | KB_X11},
+ {QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, KB_Mac},
+ {QKeySequence::MoveToEndOfDocument, 1, Qt::CTRL | Qt::Key_Down, KB_Mac},
+ {QKeySequence::MoveToEndOfDocument, 0, Qt::CTRL | Qt::Key_End, KB_Win | KB_X11},
+ {QKeySequence::MoveToEndOfDocument, 0, Qt::Key_End, KB_Mac},
+ {QKeySequence::SelectNextChar, 0, Qt::SHIFT | Qt::Key_Right, KB_All},
+ {QKeySequence::SelectPreviousChar, 0, Qt::SHIFT | Qt::Key_Left, KB_All},
+ {QKeySequence::SelectNextWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Right, KB_Mac},
+ {QKeySequence::SelectNextWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Win | KB_X11},
+ {QKeySequence::SelectPreviousWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Left, KB_Mac},
+ {QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Win | KB_X11},
+ {QKeySequence::SelectNextLine, 0, Qt::SHIFT | Qt::Key_Down, KB_All},
+ {QKeySequence::SelectPreviousLine, 0, Qt::SHIFT | Qt::Key_Up, KB_All},
+ {QKeySequence::SelectNextPage, 0, Qt::SHIFT | Qt::Key_PageDown, KB_All},
+ {QKeySequence::SelectPreviousPage, 0, Qt::SHIFT | Qt::Key_PageUp, KB_All},
+ {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, KB_Mac},
+ {QKeySequence::SelectStartOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Mac },
+ {QKeySequence::SelectStartOfLine, 0, Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
+ {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, KB_Mac},
+ {QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Mac },
+ {QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
+ {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, KB_Mac},
+ {QKeySequence::SelectStartOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only
+ {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, KB_Mac},
+ {QKeySequence::SelectEndOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only
+ {QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, KB_Mac},
+ {QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
+ {QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, KB_Mac},
+ {QKeySequence::SelectEndOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Down, KB_Mac},
+ {QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
+ {QKeySequence::SelectEndOfDocument, 0, Qt::SHIFT | Qt::Key_End, KB_Mac},
+ {QKeySequence::DeleteStartOfWord, 0, Qt::ALT | Qt::Key_Backspace, KB_Mac},
+ {QKeySequence::DeleteStartOfWord, 0, Qt::CTRL | Qt::Key_Backspace, KB_X11 | KB_Win},
+ {QKeySequence::DeleteEndOfWord, 0, Qt::ALT | Qt::Key_Delete, KB_Mac},
+ {QKeySequence::DeleteEndOfWord, 0, Qt::CTRL | Qt::Key_Delete, KB_X11 | KB_Win},
+ {QKeySequence::DeleteEndOfLine, 0, Qt::CTRL | Qt::Key_K, KB_X11}, //emacs (line edit only)
+ {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Enter, KB_All},
+ {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Return, KB_All},
+ {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Enter, KB_Mac},
+ {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, KB_Mac},
+ {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, KB_All},
+ {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, KB_All},
+ {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac},
+ {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac},
+ {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_Gnome | KB_KDE | KB_Mac},
+ {QKeySequence::FullScreen, 1, Qt::META | Qt::CTRL | Qt::Key_F, KB_Mac},
+ {QKeySequence::FullScreen, 0, Qt::ALT | Qt::Key_Enter, KB_Win},
+ {QKeySequence::FullScreen, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F, KB_KDE},
+ {QKeySequence::FullScreen, 1, Qt::CTRL | Qt::Key_F11, KB_Gnome},
+ {QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
+ {QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11}
+};
+
+const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding));
+
QPlatformThemePrivate::QPlatformThemePrivate()
: systemPalette(0)
{ }
@@ -208,10 +385,12 @@ QPixmap QPlatformTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) co
return QPixmap();
}
-QPixmap QPlatformTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
+QPixmap QPlatformTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions) const
{
Q_UNUSED(fileInfo);
Q_UNUSED(size);
+ Q_UNUSED(iconOptions);
// TODO Should return QCommonStyle pixmaps?
return QPixmap();
}
@@ -279,6 +458,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
return QVariant(true);
case IconPixmapSizes:
return QVariant::fromValue(QList<int>());
+ case DialogSnapToDefaultButton:
+ return QVariant(false);
}
return QVariant();
}
@@ -324,4 +505,99 @@ QIconEngine *QPlatformTheme::createIconEngine(const QString &iconName) const
return new QIconLoaderEngine(iconName);
}
+#if defined(Q_OS_MACX)
+static inline int maybeSwapShortcut(int shortcut)
+{
+ if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
+ uint oldshortcut = shortcut;
+ shortcut &= ~(Qt::CTRL | Qt::META);
+ if (oldshortcut & Qt::CTRL)
+ shortcut |= Qt::META;
+ if (oldshortcut & Qt::META)
+ shortcut |= Qt::CTRL;
+ }
+ return shortcut;
+}
+#endif
+
+/*!
+ Returns the key sequence that should be used for a standard action.
+
+ \since 5.2
+ */
+QList<QKeySequence> QPlatformTheme::keyBindings(QKeySequence::StandardKey key) const
+{
+ const uint platform = QPlatformThemePrivate::currentKeyPlatforms();
+ QList <QKeySequence> list;
+
+ uint N = QPlatformThemePrivate::numberOfKeyBindings;
+ int first = 0;
+ int last = N - 1;
+
+ while (first <= last) {
+ int mid = (first + last) / 2;
+ const QKeyBinding &midVal = QPlatformThemePrivate::keyBindings[mid];
+
+ if (key > midVal.standardKey){
+ first = mid + 1; // Search in top half
+ }
+ else if (key < midVal.standardKey){
+ last = mid - 1; // Search in bottom half
+ }
+ else {
+ //We may have several equal values for different platforms, so we must search in both directions
+ //search forward including current location
+ for (unsigned int i = mid; i < N - 1 ; ++i) {
+ QKeyBinding current = QPlatformThemePrivate::keyBindings[i];
+ if (current.standardKey != key)
+ break;
+ else if (current.platform & platform && current.standardKey == key) {
+ uint shortcut =
+#if defined(Q_OS_MACX)
+ maybeSwapShortcut(current.shortcut);
+#else
+ current.shortcut;
+#endif
+ if (current.priority > 0)
+ list.prepend(QKeySequence(shortcut));
+ else
+ list.append(QKeySequence(shortcut));
+ }
+ }
+
+ //search back
+ for (int i = mid - 1 ; i >= 0 ; --i) {
+ QKeyBinding current = QPlatformThemePrivate::keyBindings[i];
+ if (current.standardKey != key)
+ break;
+ else if (current.platform & platform && current.standardKey == key) {
+ uint shortcut =
+#if defined(Q_OS_MACX)
+ maybeSwapShortcut(current.shortcut);
+#else
+ current.shortcut;
+#endif
+ if (current.priority > 0)
+ list.prepend(QKeySequence(shortcut));
+ else
+ list.append(QKeySequence(shortcut));
+ }
+ }
+ break;
+ }
+ }
+ return list;
+}
+
+unsigned QPlatformThemePrivate::currentKeyPlatforms()
+{
+ const uint keyboardScheme = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt();
+ unsigned result = 1u << keyboardScheme;
+ if (keyboardScheme == QPlatformTheme::KdeKeyboardScheme
+ || keyboardScheme == QPlatformTheme::GnomeKeyboardScheme
+ || keyboardScheme == QPlatformTheme::CdeKeyboardScheme)
+ result |= KB_X11;
+ return result;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 80ba29a028..3eb103b7e0 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -53,6 +53,7 @@
#include <QtCore/QtGlobal>
#include <QtCore/QScopedPointer>
+#include <QtGui/QKeySequence>
QT_BEGIN_NAMESPACE
@@ -104,7 +105,8 @@ public:
SpellCheckUnderlineStyle,
TabAllWidgets,
IconPixmapSizes,
- PasswordMaskCharacter
+ PasswordMaskCharacter,
+ DialogSnapToDefaultButton
};
enum DialogType {
@@ -154,6 +156,7 @@ public:
ComboLineEditFont,
SmallFont,
MiniFont,
+ FixedFont,
NFonts
};
@@ -253,6 +256,11 @@ public:
AnimateToolBoxUiEffect = 0x40
};
+ enum IconOption {
+ DontUseCustomDirectoryIcons = 0x01
+ };
+ Q_DECLARE_FLAGS(IconOptions, IconOption)
+
explicit QPlatformTheme();
virtual ~QPlatformTheme();
@@ -274,10 +282,13 @@ public:
virtual QVariant themeHint(ThemeHint hint) const;
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
- virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
+ virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions = 0) const;
virtual QIconEngine *createIconEngine(const QString &iconName) const;
+ virtual QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const;
+
static QVariant defaultThemeHint(ThemeHint hint);
protected:
diff --git a/src/gui/kernel/qplatformtheme_p.h b/src/gui/kernel/qplatformtheme_p.h
index 2b965819c6..217c284a9e 100644
--- a/src/gui/kernel/qplatformtheme_p.h
+++ b/src/gui/kernel/qplatformtheme_p.h
@@ -52,6 +52,7 @@
//
#include <QtCore/QtGlobal>
+#include "private/qkeysequence_p.h"
QT_BEGIN_NAMESPACE
@@ -66,6 +67,11 @@ public:
void initializeSystemPalette();
+ static const QKeyBinding keyBindings[];
+ static const uint numberOfKeyBindings;
+
+ static unsigned currentKeyPlatforms();
+
QPalette *systemPalette;
};
diff --git a/src/gui/kernel/qsessionmanager.cpp b/src/gui/kernel/qsessionmanager.cpp
index 4ac9ab4db5..8ac3c24a8f 100644
--- a/src/gui/kernel/qsessionmanager.cpp
+++ b/src/gui/kernel/qsessionmanager.cpp
@@ -41,8 +41,12 @@
#include <qsessionmanager.h>
#include <qguiapplication.h>
+#include <qpa/qplatformsessionmanager.h>
+#include <qpa/qplatformintegration.h>
#include <private/qobject_p.h>
+#include <private/qguiapplication_p.h>
+#include <private/qsessionmanager_p.h>
#ifndef QT_NO_SESSIONMANAGER
@@ -117,32 +121,24 @@ QT_BEGIN_NAMESPACE
The default hint is \c RestartIfRunning.
*/
-
-class QSessionManagerPrivate : public QObjectPrivate
-{
-public:
- QSessionManagerPrivate(QSessionManager *m, const QString &id,
- const QString &key);
-
- QStringList restartCommand;
- QStringList discardCommand;
- const QString sessionId;
- const QString sessionKey;
- QSessionManager::RestartHint restartHint;
-};
-
-QSessionManagerPrivate::QSessionManagerPrivate(QSessionManager*,
- const QString &id,
+QSessionManagerPrivate::QSessionManagerPrivate(const QString &id,
const QString &key)
- : QObjectPrivate(), sessionId(id), sessionKey(key)
+ : QObjectPrivate()
{
+ platformSessionManager = QGuiApplicationPrivate::platformIntegration()->createPlatformSessionManager(id, key);
+ Q_ASSERT_X(platformSessionManager, "Platform session management",
+ "No platform session management, should use the default implementation");
+}
+
+QSessionManagerPrivate::~QSessionManagerPrivate()
+{
+ delete platformSessionManager;
+ platformSessionManager = 0;
}
QSessionManager::QSessionManager(QGuiApplication *app, QString &id, QString &key)
- : QObject(*(new QSessionManagerPrivate(this, id, key)), app)
+ : QObject(*(new QSessionManagerPrivate(id, key)), app)
{
- Q_D(QSessionManager);
- d->restartHint = RestartIfRunning;
}
QSessionManager::~QSessionManager()
@@ -160,7 +156,7 @@ QSessionManager::~QSessionManager()
QString QSessionManager::sessionId() const
{
Q_D(const QSessionManager);
- return d->sessionId;
+ return d->platformSessionManager->sessionId();
}
/*!
@@ -178,7 +174,7 @@ QString QSessionManager::sessionId() const
QString QSessionManager::sessionKey() const
{
Q_D(const QSessionManager);
- return d->sessionKey;
+ return d->platformSessionManager->sessionKey();
}
@@ -213,7 +209,8 @@ QString QSessionManager::sessionKey() const
*/
bool QSessionManager::allowsInteraction()
{
- return false;
+ Q_D(QSessionManager);
+ return d->platformSessionManager->allowsInteraction();
}
/*!
@@ -229,7 +226,8 @@ bool QSessionManager::allowsInteraction()
*/
bool QSessionManager::allowsErrorInteraction()
{
- return false;
+ Q_D(QSessionManager);
+ return d->platformSessionManager->allowsErrorInteraction();
}
/*!
@@ -240,6 +238,8 @@ bool QSessionManager::allowsErrorInteraction()
*/
void QSessionManager::release()
{
+ Q_D(QSessionManager);
+ d->platformSessionManager->release();
}
/*!
@@ -250,6 +250,8 @@ void QSessionManager::release()
*/
void QSessionManager::cancel()
{
+ Q_D(QSessionManager);
+ d->platformSessionManager->cancel();
}
/*!
@@ -268,7 +270,7 @@ void QSessionManager::cancel()
void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
{
Q_D(QSessionManager);
- d->restartHint = hint;
+ d->platformSessionManager->setRestartHint(hint);
}
/*!
@@ -282,7 +284,7 @@ void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
QSessionManager::RestartHint QSessionManager::restartHint() const
{
Q_D(const QSessionManager);
- return d->restartHint;
+ return d->platformSessionManager->restartHint();
}
/*!
@@ -308,7 +310,7 @@ QSessionManager::RestartHint QSessionManager::restartHint() const
void QSessionManager::setRestartCommand(const QStringList &command)
{
Q_D(QSessionManager);
- d->restartCommand = command;
+ d->platformSessionManager->setRestartCommand(command);
}
/*!
@@ -323,7 +325,7 @@ void QSessionManager::setRestartCommand(const QStringList &command)
QStringList QSessionManager::restartCommand() const
{
Q_D(const QSessionManager);
- return d->restartCommand;
+ return d->platformSessionManager->restartCommand();
}
/*!
@@ -334,7 +336,7 @@ QStringList QSessionManager::restartCommand() const
void QSessionManager::setDiscardCommand(const QStringList &command)
{
Q_D(QSessionManager);
- d->discardCommand = command;
+ d->platformSessionManager->setDiscardCommand(command);
}
/*!
@@ -349,7 +351,7 @@ void QSessionManager::setDiscardCommand(const QStringList &command)
QStringList QSessionManager::discardCommand() const
{
Q_D(const QSessionManager);
- return d->discardCommand;
+ return d->platformSessionManager->discardCommand();
}
/*!
@@ -363,8 +365,7 @@ QStringList QSessionManager::discardCommand() const
void QSessionManager::setManagerProperty(const QString &name,
const QString &value)
{
- Q_UNUSED(name);
- Q_UNUSED(value);
+ setManagerProperty(name, QStringList(value));
}
/*!
@@ -376,8 +377,8 @@ void QSessionManager::setManagerProperty(const QString &name,
void QSessionManager::setManagerProperty(const QString &name,
const QStringList &value)
{
- Q_UNUSED(name);
- Q_UNUSED(value);
+ Q_D(QSessionManager);
+ d->platformSessionManager->setManagerProperty(name, value);
}
/*!
@@ -388,7 +389,8 @@ void QSessionManager::setManagerProperty(const QString &name,
*/
bool QSessionManager::isPhase2() const
{
- return false;
+ Q_D(const QSessionManager);
+ return d->platformSessionManager->isPhase2();
}
/*!
@@ -409,6 +411,8 @@ bool QSessionManager::isPhase2() const
*/
void QSessionManager::requestPhase2()
{
+ Q_D(QSessionManager);
+ d->platformSessionManager->requestPhase2();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/maliit/main.cpp b/src/gui/kernel/qsessionmanager_p.h
index ca4845afd7..dd249fdb67 100644
--- a/src/plugins/platforminputcontexts/maliit/main.cpp
+++ b/src/gui/kernel/qsessionmanager_p.h
@@ -1,9 +1,10 @@
/****************************************************************************
**
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,30 +40,43 @@
**
****************************************************************************/
-#include <qpa/qplatforminputcontextplugin_p.h>
-#include <QtCore/QStringList>
-#include "qmaliitplatforminputcontext.h"
+#ifndef QSESSIONMANAGER_P_H
+#define QSESSIONMANAGER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qobject_p.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+
+#ifndef QT_NO_SESSIONMANAGER
QT_BEGIN_NAMESPACE
-class QMaliitPlatformInputContextPlugin : public QPlatformInputContextPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" FILE "maliit.json")
+class QPlatformSessionManager;
+class QSessionManagerPrivate : public QObjectPrivate
+{
public:
- QPlatformInputContext *create(const QString&, const QStringList&);
-};
+ QSessionManagerPrivate(const QString &id,
+ const QString &key);
-QPlatformInputContext *QMaliitPlatformInputContextPlugin::create(const QString& system, const QStringList& paramList)
-{
- Q_UNUSED(paramList);
+ virtual ~QSessionManagerPrivate();
- if (system.compare(system, QStringLiteral("maliit"), Qt::CaseInsensitive) == 0)
- return new QMaliitPlatformInputContext;
- return 0;
-}
+ QPlatformSessionManager *platformSessionManager;
+};
QT_END_NAMESPACE
-#include "main.moc"
+#endif // QT_NO_SESSIONMANAGER
+
+#endif // QSESSIONMANAGER_P_H
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index cd822090e2..513e21937e 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -324,6 +324,9 @@ bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
{
Q_D(QShortcutMap);
+ if (e->key() == Qt::Key_unknown)
+ return false;
+
bool wasAccepted = e->isAccepted();
bool wasSpontaneous = e->spont;
if (d->currentState == QKeySequence::NoMatch) {
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 30b12835f7..a302f2186c 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -218,4 +218,15 @@ bool QStyleHints::useRtlExtensions() const
return hint(QPlatformIntegration::UseRtlExtensions).toBool();
}
+/*!
+ Returns \c true if focus objects (line edits etc) should receive
+ input focus after a touch/mouse release. This is normal behavior on
+ touch platforms. On desktop platforms, the standard is to set
+ focus already on touch/mouse press.
+*/
+bool QStyleHints::setFocusOnTouchRelease() const
+{
+ return hint(QPlatformIntegration::SetFocusOnTouchRelease).toBool();
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 64ef182aab..a0facd5f94 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -65,6 +65,7 @@ public:
QChar passwordMaskCharacter() const;
qreal fontSmoothingGamma() const;
bool useRtlExtensions() const;
+ bool setFocusOnTouchRelease() const;
private:
friend class QGuiApplication;
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index 02c6dd9efc..3ad4b4161e 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -140,6 +140,16 @@ QTouchDevice::Capabilities QTouchDevice::capabilities() const
}
/*!
+ Returns the maximum number of simultaneous touch points (fingers) that
+ can be detected.
+ \since 5.2
+ */
+int QTouchDevice::maximumTouchPoints() const
+{
+ return d->maxTouchPoints;
+}
+
+/*!
Returns the touch device name.
This string may often be empty. It is however useful for systems that have
@@ -169,6 +179,15 @@ void QTouchDevice::setCapabilities(Capabilities caps)
}
/*!
+ Sets the maximum number of simultaneous touchpoints \a max
+ supported by the device and its driver.
+ */
+void QTouchDevice::setMaximumTouchPoints(int max)
+{
+ d->maxTouchPoints = max;
+}
+
+/*!
Sets the \a name (a unique identifier) for the device. In most systems it is
enough to leave this unset and keep the default empty name. This identifier
becomes important when having multiple touch devices and a need to
diff --git a/src/gui/kernel/qtouchdevice.h b/src/gui/kernel/qtouchdevice.h
index 312bdce3e6..6aca93907c 100644
--- a/src/gui/kernel/qtouchdevice.h
+++ b/src/gui/kernel/qtouchdevice.h
@@ -75,10 +75,12 @@ public:
QString name() const;
DeviceType type() const;
Capabilities capabilities() const;
+ int maximumTouchPoints() const;
void setName(const QString &name);
void setType(DeviceType devType);
void setCapabilities(Capabilities caps);
+ void setMaximumTouchPoints(int max);
private:
QTouchDevicePrivate *d;
diff --git a/src/gui/kernel/qtouchdevice_p.h b/src/gui/kernel/qtouchdevice_p.h
index 435f8a5c37..fb87f49736 100644
--- a/src/gui/kernel/qtouchdevice_p.h
+++ b/src/gui/kernel/qtouchdevice_p.h
@@ -64,12 +64,14 @@ class QTouchDevicePrivate
public:
QTouchDevicePrivate()
: type(QTouchDevice::TouchScreen),
- caps(QTouchDevice::Position)
+ caps(QTouchDevice::Position),
+ maxTouchPoints(1)
{ }
QTouchDevice::DeviceType type;
QTouchDevice::Capabilities caps;
QString name;
+ int maxTouchPoints;
static void registerDevice(QTouchDevice *dev);
static bool isRegistered(QTouchDevice *dev);
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 6fc63fe96c..7b57313645 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -298,13 +298,13 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
handleWheelEvent(tlw, timestamp, local, global, QPoint(), point, mods);
}
-void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleWheelEvent(w, time, local, global, pixelDelta, angleDelta, mods);
+ handleWheelEvent(w, time, local, global, pixelDelta, angleDelta, mods, phase);
}
-void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase)
{
// Qt 4 sends two separate wheel events for horizontal and vertical
// deltas. For Qt 5 we want to send the deltas in one event, but at the
@@ -315,19 +315,21 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Angle deltas must always be sent in addition to pixel deltas.
QWindowSystemInterfacePrivate::WheelEvent *e;
- if (angleDelta.isNull())
+ // Pass Qt::ScrollBegin and Qt::ScrollEnd through
+ // even if the wheel delta is null.
+ if (angleDelta.isNull() && phase == Qt::ScrollUpdate)
return;
// Simple case: vertical deltas only:
if (angleDelta.y() != 0 && angleDelta.x() == 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
// Simple case: horizontal deltas only:
if (angleDelta.y() == 0 && angleDelta.x() != 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
@@ -335,12 +337,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Both horizontal and vertical deltas: Send two wheel events.
// The first event contains the Qt 5 pixel and angle delta as points,
// and in addition the Qt 4 compatibility vertical angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
// The second event contains null pixel and angle points and the
// Qt 4 compatibility horizontal angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -692,6 +694,15 @@ void QWindowSystemInterface::handleContextMenuEvent(QWindow *w, bool mouseTrigge
}
#endif
+#ifndef QT_NO_WHATSTHIS
+void QWindowSystemInterface::handleEnterWhatsThisEvent()
+{
+ QWindowSystemInterfacePrivate::WindowSystemEvent *e =
+ new QWindowSystemInterfacePrivate::WindowSystemEvent(QWindowSystemInterfacePrivate::EnterWhatsThisMode);
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+#endif
+
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPoint &p) {
dbg.nospace() << "TouchPoint(" << p.id << " @" << p.normalPosition << " press " << p.pressure << " vel " << p.velocity << " state " << (int)p.state;
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index b0327701bb..cac943cda1 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -103,8 +103,8 @@ public:
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
ushort count = 1);
- static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier);
+ static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate);
+ static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate);
// Wheel event compatibility functions. Will be removed: do not use.
static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier);
@@ -183,6 +183,9 @@ public:
const QPoint &pos, const QPoint &globalPos,
Qt::KeyboardModifiers modifiers);
#endif
+#ifndef QT_NO_WHATSTHIS
+ static void handleEnterWhatsThisEvent();
+#endif
// For event dispatcher implementations
static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 398df0a96f..46479701cc 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -90,6 +90,7 @@ public:
TabletLeaveProximity = UserInputEvent | 0x16,
PlatformPanel = UserInputEvent | 0x17,
ContextMenu = UserInputEvent | 0x18,
+ EnterWhatsThisMode = UserInputEvent | 0x19,
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
WindowScreenChanged = 0x21
@@ -217,14 +218,15 @@ public:
class WheelEvent : public InputEvent {
public:
WheelEvent(QWindow *w, ulong time, const QPointF & local, const QPointF & global, QPoint pixelD, QPoint angleD, int qt4D, Qt::Orientation qt4O,
- Qt::KeyboardModifiers mods)
- : InputEvent(w, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D), qt4Orientation(qt4O), localPos(local), globalPos(global) { }
+ Qt::KeyboardModifiers mods, Qt::ScrollPhase phase = Qt::ScrollUpdate)
+ : InputEvent(w, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D), qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase) { }
QPoint pixelDelta;
QPoint angleDelta;
int qt4Delta;
Qt::Orientation qt4Orientation;
QPointF localPos;
QPointF globalPos;
+ Qt::ScrollPhase phase;
};
class KeyEvent : public InputEvent {
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index 784297ca70..7446d27dab 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -160,6 +160,25 @@ QVector2D::QVector2D(const QVector4D& vector)
\sa y(), setX()
*/
+/*! \fn float &QVector2D::operator[](int i)
+ \since 5.2
+
+ Returns the component of the vector at index position \a i
+ as a modifiable reference.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a i
+ < 2).
+*/
+
+/*! \fn float QVector2D::operator[](int i) const
+ \since 5.2
+
+ Returns the component of the vector at index position \a i.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a i
+ < 2).
+*/
+
/*!
Returns the length of the vector from the origin.
diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h
index b3c2272287..55e606ec35 100644
--- a/src/gui/math3d/qvector2d.h
+++ b/src/gui/math3d/qvector2d.h
@@ -76,6 +76,9 @@ public:
void setX(float x);
void setY(float y);
+ float &operator[](int i);
+ float operator[](int i) const;
+
float length() const;
float lengthSquared() const;
@@ -145,6 +148,18 @@ inline float QVector2D::y() const { return yp; }
inline void QVector2D::setX(float aX) { xp = aX; }
inline void QVector2D::setY(float aY) { yp = aY; }
+inline float &QVector2D::operator[](int i)
+{
+ Q_ASSERT(uint(i) < 2u);
+ return *(&xp + i);
+}
+
+inline float QVector2D::operator[](int i) const
+{
+ Q_ASSERT(uint(i) < 2u);
+ return *(&xp + i);
+}
+
inline QVector2D &QVector2D::operator+=(const QVector2D &vector)
{
xp += vector.xp;
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 5537562b61..226483c227 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -196,6 +196,25 @@ QVector3D::QVector3D(const QVector4D& vector)
\sa z(), setX(), setY()
*/
+/*! \fn float &QVector3D::operator[](int i)
+ \since 5.2
+
+ Returns the component of the vector at index position \a i
+ as a modifiable reference.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a i
+ < 3).
+*/
+
+/*! \fn float QVector3D::operator[](int i) const
+ \since 5.2
+
+ Returns the component of the vector at index position \a i.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a i
+ < 3).
+*/
+
/*!
Returns the normalized unit vector form of this vector.
diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h
index 49d9ca6bf8..c880930935 100644
--- a/src/gui/math3d/qvector3d.h
+++ b/src/gui/math3d/qvector3d.h
@@ -79,6 +79,9 @@ public:
void setY(float y);
void setZ(float z);
+ float &operator[](int i);
+ float operator[](int i) const;
+
float length() const;
float lengthSquared() const;
@@ -160,6 +163,18 @@ inline void QVector3D::setX(float aX) { xp = aX; }
inline void QVector3D::setY(float aY) { yp = aY; }
inline void QVector3D::setZ(float aZ) { zp = aZ; }
+inline float &QVector3D::operator[](int i)
+{
+ Q_ASSERT(uint(i) < 3u);
+ return *(&xp + i);
+}
+
+inline float QVector3D::operator[](int i) const
+{
+ Q_ASSERT(uint(i) < 3u);
+ return *(&xp + i);
+}
+
inline QVector3D &QVector3D::operator+=(const QVector3D &vector)
{
xp += vector.xp;
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index 7ced99dfeb..2247e95d5e 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -225,6 +225,25 @@ QVector4D::QVector4D(const QVector3D& vector, float wpos)
\sa w(), setX(), setY(), setZ()
*/
+/*! \fn float &QVector4D::operator[](int i)
+ \since 5.2
+
+ Returns the component of the vector at index position \a i
+ as a modifiable reference.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a i
+ < 4).
+*/
+
+/*! \fn float QVector4D::operator[](int i) const
+ \since 5.2
+
+ Returns the component of the vector at index position \a i.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a i
+ < 4).
+*/
+
/*!
Returns the length of the vector from the origin.
diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h
index 4bd3822133..810380b805 100644
--- a/src/gui/math3d/qvector4d.h
+++ b/src/gui/math3d/qvector4d.h
@@ -82,6 +82,9 @@ public:
void setZ(float z);
void setW(float w);
+ float &operator[](int i);
+ float operator[](int i) const;
+
float length() const;
float lengthSquared() const;
@@ -158,6 +161,18 @@ inline void QVector4D::setY(float aY) { yp = aY; }
inline void QVector4D::setZ(float aZ) { zp = aZ; }
inline void QVector4D::setW(float aW) { wp = aW; }
+inline float &QVector4D::operator[](int i)
+{
+ Q_ASSERT(uint(i) < 4u);
+ return *(&xp + i);
+}
+
+inline float QVector4D::operator[](int i) const
+{
+ Q_ASSERT(uint(i) < 4u);
+ return *(&xp + i);
+}
+
inline QVector4D &QVector4D::operator+=(const QVector4D &vector)
{
xp += vector.xp;
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 90416db72b..247ecf7351 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -1012,23 +1012,28 @@ QOpenGLFramebufferObjectFormat QOpenGLFramebufferObject::format() const
Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
{
- QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_RGB32);
int w = size.width();
int h = size.height();
+ while (glGetError());
+
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32);
#ifdef QT_OPENGL_ES
GLint fmt = GL_BGRA_EXT;
#else
GLint fmt = GL_BGRA;
#endif
- while (glGetError());
glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img.bits());
- if (glGetError()) {
- glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
- img = img.rgbSwapped();
- }
- return img.mirrored();
+ if (!glGetError())
+ return img.mirrored();
+#endif
+
+ QImage rgbaImage(size, (alpha_format && include_alpha) ? QImage::Format_RGBA8888_Premultiplied
+ : QImage::Format_RGBX8888);
+ glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits());
+ return rgbaImage.mirrored();
}
/*!
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 3737df7497..60591a34d2 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -141,8 +141,8 @@ QT_BEGIN_NAMESPACE
/*!
\enum QOpenGLFunctions::OpenGLFeature
- This enum defines OpenGL/ES 2.0 features that may be optional
- on other platforms.
+ This enum defines OpenGL and OpenGL ES features whose presence
+ may depend on the implementation.
\value Multitexture glActiveTexture() function is available.
\value Shaders Shader functions are available.
@@ -158,6 +158,7 @@ QT_BEGIN_NAMESPACE
\value StencilSeparate Separate stencil functions are available.
\value NPOTTextures Non power of two textures are available.
\value NPOTTextureRepeat Non power of two textures can use GL_REPEAT as wrap parameter.
+ \value FixedFunctionPipeline The fixed function pipeline is available.
*/
// Hidden private fields for additional extension data.
@@ -331,6 +332,13 @@ static int qt_gl_resolve_features()
if (format.majorVersion() >= 3)
features |= QOpenGLFunctions::Framebuffers;
+ const QPair<int, int> version = format.version();
+ if (version < qMakePair(3, 0)
+ || (version == qMakePair(3, 0) && format.testOption(QSurfaceFormat::DeprecatedFunctions))
+ || (version == qMakePair(3, 1) && extensions.match("GL_ARB_compatibility"))
+ || (version >= qMakePair(3, 2) && format.profile() == QSurfaceFormat::CompatibilityProfile)) {
+ features |= QOpenGLFunctions::FixedFunctionPipeline;
+ }
return features;
#endif
}
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index 1548ad4a24..9d8da209ad 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -199,7 +199,8 @@ public:
Multisample = 0x0400,
StencilSeparate = 0x0800,
NPOTTextures = 0x1000,
- NPOTTextureRepeat = 0x2000
+ NPOTTextureRepeat = 0x2000,
+ FixedFunctionPipeline = 0x4000
};
Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature)
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 47ba27d72a..aadcc0f686 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -91,9 +91,12 @@ SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
AVX_SOURCES += painting/qdrawhelper_avx.cpp
-NEON_SOURCES += painting/qdrawhelper_neon.cpp
-NEON_HEADERS += painting/qdrawhelper_neon_p.h
-NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
+
+!ios {
+ NEON_SOURCES += painting/qdrawhelper_neon.cpp
+ NEON_HEADERS += painting/qdrawhelper_neon_p.h
+ NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
+}
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 6d9168ecf4..23eaa9a3e7 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -604,7 +604,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Mono
0, // Format_Invalid,
@@ -622,7 +625,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_MonoLSB
0, // Format_Invalid,
@@ -640,7 +646,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Indexed8
0, // Format_Invalid,
@@ -658,7 +667,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB32
0, // Format_Invalid,
@@ -676,7 +688,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32
0, // Format_Invalid,
@@ -694,7 +709,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32_Premultiplied
0, // Format_Invalid,
@@ -712,7 +730,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB16
0, // Format_Invalid,
@@ -730,7 +751,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8565_Premultiplied
0, // Format_Invalid,
@@ -748,7 +772,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB666
0, // Format_Invalid,
@@ -766,7 +793,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB6666_Premultiplied
0, // Format_Invalid,
@@ -784,7 +814,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB555
0, // Format_Invalid,
@@ -802,7 +835,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8555_Premultiplied
0, // Format_Invalid,
@@ -820,7 +856,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB888
0, // Format_Invalid,
@@ -838,7 +877,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB444
0, // Format_Invalid,
@@ -856,7 +898,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB4444_Premultiplied
0, // Format_Invalid,
@@ -874,7 +919,85 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBX8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
+ },
+ { // Format_RGBA8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBA8888_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
}
};
@@ -896,7 +1019,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Mono
0, // Format_Invalid,
@@ -914,7 +1040,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_MonoLSB
0, // Format_Invalid,
@@ -932,7 +1061,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Indexed8
0, // Format_Invalid,
@@ -950,7 +1082,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB32
0, // Format_Invalid,
@@ -968,7 +1103,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32
0, // Format_Invalid,
@@ -986,7 +1124,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32_Premultiplied
0, // Format_Invalid,
@@ -1004,7 +1145,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB16
0, // Format_Invalid,
@@ -1022,7 +1166,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8565_Premultiplied
0, // Format_Invalid,
@@ -1040,7 +1187,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB666
0, // Format_Invalid,
@@ -1058,7 +1208,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB6666_Premultiplied
0, // Format_Invalid,
@@ -1076,7 +1229,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB555
0, // Format_Invalid,
@@ -1094,7 +1250,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8555_Premultiplied
0, // Format_Invalid,
@@ -1112,7 +1271,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB888
0, // Format_Invalid,
@@ -1130,7 +1292,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB444
0, // Format_Invalid,
@@ -1148,7 +1313,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB4444_Premultiplied
0, // Format_Invalid,
@@ -1166,7 +1334,85 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBX8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_blend_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
+ },
+ { // Format_RGBA8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBA8888_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_blend_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
}
};
@@ -1187,7 +1433,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Mono
0, // Format_Invalid,
@@ -1205,7 +1454,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_MonoLSB
0, // Format_Invalid,
@@ -1223,7 +1475,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Indexed8
0, // Format_Invalid,
@@ -1241,7 +1496,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB32
0, // Format_Invalid,
@@ -1259,7 +1517,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32
0, // Format_Invalid,
@@ -1277,7 +1538,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32_Premultiplied
0, // Format_Invalid,
@@ -1295,7 +1559,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB16
0, // Format_Invalid,
@@ -1313,7 +1580,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8565_Premultiplied
0, // Format_Invalid,
@@ -1331,7 +1601,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB666
0, // Format_Invalid,
@@ -1349,7 +1622,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB6666_Premultiplied
0, // Format_Invalid,
@@ -1367,7 +1643,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB555
0, // Format_Invalid,
@@ -1385,7 +1664,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8555_Premultiplied
0, // Format_Invalid,
@@ -1403,7 +1685,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB888
0, // Format_Invalid,
@@ -1421,7 +1706,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB444
0, // Format_Invalid,
@@ -1439,7 +1727,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB4444_Premultiplied
0, // Format_Invalid,
@@ -1457,7 +1748,85 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBX8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
+ },
+ { // Format_RGBA8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBA8888_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
}
};
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 12ca84d8d1..c93320c491 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -90,7 +90,8 @@ QT_BEGIN_NAMESPACE
specified.
A color can be set by passing an RGB string (such as "#112233"),
- or a color name (such as "blue"), to the setNamedColor() function.
+ or an ARGB string (such as "#ff112233") or a color name (such as "blue"),
+ to the setNamedColor() function.
The color names are taken from the SVG 1.0 color names. The name()
function returns the name of the color in the format
"#RRGGBB". Colors can also be set using setRgb(), setHsv() and
@@ -301,6 +302,17 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QColor::NameFormat
+
+ How to format the output of the name() function
+
+ \value HexRgb #RRGGBB A "#" character followed by three two-digit hexadecimal numbers (i.e. \c{#RRGGBB}).
+ \value HexArgb #AARRGGBB A "#" character followed by four two-digit hexadecimal numbers (i.e. \c{#AARRGGBB}).
+
+ \sa name()
+*/
+
+/*!
\fn Spec QColor::spec() const
Returns how the color was specified.
@@ -489,8 +501,28 @@ QColor::QColor(Spec spec)
QString QColor::name() const
{
+ return name(HexRgb);
+}
+
+/*!
+ \since 5.2
+
+ Returns the name of the color in the specified \a format.
+
+ \sa setNamedColor(), NameFormat
+*/
+
+QString QColor::name(NameFormat format) const
+{
QString s;
- s.sprintf("#%02x%02x%02x", red(), green(), blue());
+ switch (format) {
+ case HexRgb:
+ s.sprintf("#%02x%02x%02x", red(), green(), blue());
+ break;
+ case HexArgb:
+ s.sprintf("#%02x%02x%02x%02x", alpha(), red(), green(), blue());
+ break;
+ }
return s;
}
@@ -501,6 +533,7 @@ QString QColor::name() const
\list
\li #RGB (each of R, G, and B is a single hex digit)
\li #RRGGBB
+ \li #AARRGGBB (Since 5.2)
\li #RRRGGGBBB
\li #RRRRGGGGBBBB
\li A name from the list of colors defined in the list of \l{http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG color keyword names}
@@ -545,9 +578,9 @@ bool QColor::setColorFromString(const QString &name)
}
if (name.startsWith(QLatin1Char('#'))) {
- QRgb rgb;
- if (qt_get_hex_rgb(name.constData(), name.length(), &rgb)) {
- setRgb(rgb);
+ QRgb rgba;
+ if (qt_get_hex_rgb(name.constData(), name.length(), &rgba)) {
+ setRgba(rgba);
return true;
} else {
invalidate();
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index ef3503e8d8..1ede5a3682 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -65,6 +65,7 @@ class Q_GUI_EXPORT QColor
{
public:
enum Spec { Invalid, Rgb, Hsv, Cmyk, Hsl };
+ enum NameFormat { HexRgb, HexArgb };
QColor();
QColor(Qt::GlobalColor color);
@@ -77,7 +78,9 @@ public:
bool isValid() const;
+ // ### Qt 6: merge overloads
QString name() const;
+ QString name(NameFormat format) const;
void setNamedColor(const QString& name);
static QStringList colorNames();
diff --git a/src/gui/painting/qcolor_p.cpp b/src/gui/painting/qcolor_p.cpp
index 35e607ec54..b913f5338c 100644
--- a/src/gui/painting/qcolor_p.cpp
+++ b/src/gui/painting/qcolor_p.cpp
@@ -79,7 +79,8 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb)
return false;
name++;
int len = qstrlen(name);
- int r, g, b;
+ int a, r, g, b;
+ a = 255;
if (len == 12) {
r = hex2int(name);
g = hex2int(name + 4);
@@ -88,6 +89,11 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb)
r = hex2int(name);
g = hex2int(name + 3);
b = hex2int(name + 6);
+ } else if (len == 8) {
+ a = hex2int(name);
+ r = hex2int(name + 2);
+ g = hex2int(name + 4);
+ b = hex2int(name + 6);
} else if (len == 6) {
r = hex2int(name);
g = hex2int(name + 2);
@@ -99,11 +105,11 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb)
} else {
r = g = b = -1;
}
- if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255) {
+ if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255 || (uint)a > 255) {
*rgb = 0;
return false;
}
- *rgb = qRgb(r, g ,b);
+ *rgb = qRgba(r, g ,b, a);
return true;
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index de0ab53c1b..a037545dc2 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -255,6 +255,33 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src
return buffer;
}
+static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
+{
+ Q_ASSERT(layout->redWidth <= 8);
+ Q_ASSERT(layout->greenWidth <= 8);
+ Q_ASSERT(layout->blueWidth <= 8);
+ Q_ASSERT(layout->alphaWidth == 0);
+
+ const uint redMask = (1 << layout->redWidth) - 1;
+ const uint greenMask = (1 << layout->greenWidth) - 1;
+ const uint blueMask = (1 << layout->blueWidth) - 1;
+
+ const uchar redRightShift = 24 - layout->redWidth;
+ const uchar greenRightShift = 16 - layout->greenWidth;
+ const uchar blueRightShift = 8 - layout->blueWidth;
+
+ for (int i = 0; i < count; ++i) {
+ uint color = INV_PREMUL(src[i]);
+ uint red = ((color >> redRightShift) & redMask) << layout->redShift;
+ uint green = ((color >> greenRightShift) & greenMask) << layout->greenShift;
+ uint blue = ((color >> blueRightShift) & blueMask) << layout->blueShift;
+ uint alpha = 0xff << layout->alphaShift;
+ buffer[i] = red | green | blue | alpha;
+ }
+ return buffer;
+}
+
template <QPixelLayout::BPP bpp> static
uint QT_FASTCALL fetchPixel(const uchar *src, int index);
@@ -386,7 +413,16 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
{ 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied
{ 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888
{ 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444
- { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM } // Format_ARGB4444_Premultiplied
+ { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB4444_Premultiplied
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888_Premultiplied
+#else
+ { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
+ { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 (ABGR32)
+ { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM } // Format_RGBA8888_Premultiplied
+#endif
};
FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = {
@@ -490,7 +526,10 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
destFetch, // Format_ARGB8555_Premultiplied
destFetch, // Format_RGB888
destFetch, // Format_RGB444
- destFetch // Format_ARGB4444_Premultiplied
+ destFetch, // Format_ARGB4444_Premultiplied
+ destFetch, // Format_RGBX8888
+ destFetch, // Format_RGBA8888
+ destFetch, // Format_RGBA8888_Premultiplied
};
/*
@@ -622,7 +661,10 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
destStore, // Format_ARGB8555_Premultiplied
destStore, // Format_RGB888
destStore, // Format_RGB444
- destStore // Format_ARGB4444_Premultiplied
+ destStore, // Format_ARGB4444_Premultiplied
+ destStore, // Format_RGBX8888
+ destStore, // Format_RGBA8888
+ destStore // Format_RGBA8888_Premultiplied
};
/*
@@ -1766,7 +1808,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchUntransformed, // ARGB8555_Premultiplied
fetchUntransformed, // RGB888
fetchUntransformed, // RGB444
- fetchUntransformed // ARGB4444_Premultiplied
+ fetchUntransformed, // ARGB4444_Premultiplied
+ fetchUntransformed, // RGBX8888
+ fetchUntransformed, // RGBA8888
+ fetchUntransformed // RGBA8888_Premultiplied
},
// Tiled
{
@@ -1785,7 +1830,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchUntransformed, // ARGB8555_Premultiplied
fetchUntransformed, // RGB888
fetchUntransformed, // RGB444
- fetchUntransformed // ARGB4444_Premultiplied
+ fetchUntransformed, // ARGB4444_Premultiplied
+ fetchUntransformed, // RGBX8888
+ fetchUntransformed, // RGBA8888
+ fetchUntransformed // RGBA8888_Premultiplied
},
// Transformed
{
@@ -1805,6 +1853,9 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformed<BlendTransformed>, // RGB888
fetchTransformed<BlendTransformed>, // RGB444
fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGBX8888
+ fetchTransformed<BlendTransformed>, // RGBA8888
+ fetchTransformed<BlendTransformed>, // RGBA8888_Premultiplied
},
{
0, // TransformedTiled
@@ -1823,6 +1874,9 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformed<BlendTransformedTiled>, // RGB888
fetchTransformed<BlendTransformedTiled>, // RGB444
fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGBX8888
+ fetchTransformed<BlendTransformedTiled>, // RGBA8888
+ fetchTransformed<BlendTransformedTiled>, // RGBA8888_Premultiplied
},
{
0, // Bilinear
@@ -1840,7 +1894,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8555_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB888
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinear> // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGBX8888
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888
+ fetchTransformedBilinear<BlendTransformedBilinear> // RGBA8888_Premultiplied
},
{
0, // BilinearTiled
@@ -1858,7 +1915,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB888
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinearTiled> // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBX8888
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888
+ fetchTransformedBilinear<BlendTransformedBilinearTiled> // RGBA8888_Premultiplied
},
};
@@ -5268,6 +5328,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
},
// Tiled
{
@@ -5287,6 +5350,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
},
// Transformed
{
@@ -5306,6 +5372,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
},
// TransformedTiled
{
@@ -5324,6 +5393,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
blend_src_generic
},
// Bilinear
@@ -5344,6 +5416,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
},
// BilinearTiled
{
@@ -5363,6 +5438,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic, // RGB888
blend_src_generic, // RGB444
blend_src_generic, // ARGB4444_Premultiplied
+ blend_src_generic, // RGBX8888
+ blend_src_generic, // RGBA8888
+ blend_src_generic, // RGBA8888_Premultiplied
}
};
@@ -5823,9 +5901,9 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
}
}
-static void qt_rectfill_quint32(QRasterBuffer *rasterBuffer,
- int x, int y, int width, int height,
- quint32 color)
+static void qt_rectfill_argb32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
color, x, y, width, height, rasterBuffer->bytesPerLine());
@@ -5839,14 +5917,30 @@ static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer,
qConvertRgb32To16(color), x, y, width, height, rasterBuffer->bytesPerLine());
}
-static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer,
- int x, int y, int width, int height,
- quint32 color)
+static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine());
}
+static void qt_rectfill_rgba(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
+{
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ ARGB2RGBA(color), x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
+static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
+{
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ ARGB2RGBA(INV_PREMUL(color)), x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
// Map table for destination image format. Contains function pointers
// for blends of various types unto the destination
@@ -5880,7 +5974,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_quint32
+ qt_rectfill_argb32
},
// Format_ARGB32,
{
@@ -5889,7 +5983,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_nonpremul_quint32
+ qt_rectfill_nonpremul_argb32
},
// Format_ARGB32_Premultiplied
{
@@ -5898,7 +5992,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_quint32
+ qt_rectfill_argb32
},
// Format_RGB16
{
@@ -5956,6 +6050,48 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
blend_color_generic,
blend_src_generic,
0, 0, 0, 0
+ },
+ // Format_RGBX8888
+ {
+ blend_color_generic,
+ qt_gradient_quint32,
+ qt_bitmapblit_quint32,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_alphamapblit_quint32,
+ qt_alphargbblit_quint32,
+#else
+ 0,
+ 0,
+#endif
+ qt_rectfill_rgba
+ },
+ // Format_RGBA8888
+ {
+ blend_color_generic,
+ qt_gradient_quint32,
+ qt_bitmapblit_quint32,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_alphamapblit_quint32,
+ qt_alphargbblit_quint32,
+#else
+ 0,
+ 0,
+#endif
+ qt_rectfill_nonpremul_rgba
+ },
+ // Format_RGB8888_Premultiplied
+ {
+ blend_color_generic,
+ qt_gradient_quint32,
+ qt_bitmapblit_quint32,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_alphamapblit_quint32,
+ qt_alphargbblit_quint32,
+#else
+ 0,
+ 0,
+#endif
+ qt_rectfill_rgba
}
};
@@ -6043,6 +6179,9 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_avx;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_avx;
+ qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_avx;
+ qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_avx;
+ qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
extern void qt_scale_image_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -6052,6 +6191,10 @@ void qInitDrawhelperAsm()
int const_alpha);
qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
+ qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
+#endif
#endif
#ifdef QT_COMPILER_SUPPORTS_SSE2
} else if (features & SSE2) {
@@ -6061,6 +6204,9 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
+ qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -6070,6 +6216,10 @@ void qInitDrawhelperAsm()
int const_alpha);
qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+#endif
#endif
}
@@ -6088,6 +6238,12 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+#endif
extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length);
@@ -6104,6 +6260,10 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+#endif
}
#endif // SSSE3
@@ -6122,6 +6282,12 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
+#endif
extern const uint * QT_FASTCALL qt_fetch_radial_gradient_avx(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length);
@@ -6163,7 +6329,7 @@ void qInitDrawhelperAsm()
}
#endif // IWMMXT
-#if defined(QT_COMPILER_SUPPORTS_NEON)
+#if defined(QT_COMPILER_SUPPORTS_NEON) && !defined(Q_OS_IOS)
if (features & NEON) {
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
@@ -6172,6 +6338,12 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+#endif
qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 0b8a41c904..f4c29996b4 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -653,6 +653,30 @@ static Q_ALWAYS_INLINE uint PREMUL(uint x) {
}
#endif
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
+ quint32 rgb = x >> 8;
+ quint32 a = x << 24;
+ return a | rgb;
+}
+
+static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
+ quint32 rgb = x << 8;
+ quint32 a = x >> 24;
+ return a | rgb;
+}
+#else
+static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
+ // RGBA8888 is ABGR32 on little endian.
+ quint32 ag = x & 0xff00ff00;
+ quint32 rg = x & 0x00ff00ff;
+ return ag | (rg << 16) | (rg >> 16);
+}
+
+static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
+ return RGBA2ARGB(x);
+}
+#endif
static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16(uint x, uint a) {
a += 1;
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 27cb08f353..89ccdd42f0 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -1017,7 +1017,7 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
return QImage();
}
- if (src.format() == QImage::Format_ARGB32_Premultiplied)
+ if (src.format() == QImage::Format_ARGB32_Premultiplied || src.format() == QImage::Format_RGBA8888_Premultiplied)
qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0),
0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4);
else
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 747881bbd1..087231df43 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -529,7 +529,10 @@ MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3] =
{ 0, 0, 0 }, // Format_ARGB8555_Premultiplied,
{ 0, 0, 0 }, // Format_RGB888,
{ 0, 0, 0 }, // Format_RGB444,
- { 0, 0, 0 } // Format_ARGB4444_Premultiplied,
+ { 0, 0, 0 }, // Format_ARGB4444_Premultiplied,
+ { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBX8888,
+ { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBA8888,
+ { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 } // Format_RGBA8888_Premultiplied,
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index bb0c441b40..f855e9e32d 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -89,9 +89,9 @@ QTextItemIntCopy::QTextItemIntCopy(const QTextItem &item)
QTextItemIntCopy::~QTextItemIntCopy()
{
- delete m_item.chars;
- delete m_item.logClusters;
- delete m_item.glyphs.data();
+ delete [] m_item.chars;
+ delete [] m_item.logClusters;
+ delete [] m_item.glyphs.data();
if (!m_item.fontEngine->ref.deref())
delete m_item.fontEngine;
}
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index d1e9b81faa..3586b3452a 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -72,6 +72,7 @@
#include "qoutlinemapper_p.h"
#include <limits.h>
+#include <algorithm>
#ifdef Q_OS_WIN
# include <qvarlengtharray.h>
@@ -435,6 +436,8 @@ void QRasterPaintEngine::init()
case QImage::Format_ARGB4444_Premultiplied:
case QImage::Format_ARGB32_Premultiplied:
case QImage::Format_ARGB32:
+ case QImage::Format_RGBA8888_Premultiplied:
+ case QImage::Format_RGBA8888:
gccaps |= PorterDuff;
break;
case QImage::Format_RGB32:
@@ -443,6 +446,7 @@ void QRasterPaintEngine::init()
case QImage::Format_RGB666:
case QImage::Format_RGB888:
case QImage::Format_RGB16:
+ case QImage::Format_RGBX8888:
break;
default:
break;
@@ -1850,7 +1854,7 @@ static bool splitPolygon(const QPointF *points, int pointCount, QVector<QPointF>
for (int i = 0; i < pointCount; ++i)
sorted << points + i;
- qSort(sorted.begin(), sorted.end(), isAbove);
+ std::sort(sorted.begin(), sorted.end(), isAbove);
qreal splitY = sorted.at(sorted.size() / 2)->y();
@@ -2261,6 +2265,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_RGBA8888_Premultiplied:
// Combine premultiplied color with the opacity set on the painter.
d->solid_color_filler.solid.color =
((((color & 0x00ff00ff) * s->intOpacity) >> 8) & 0x00ff00ff)
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index cfb9d71f5c..d36a2d46f8 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -115,12 +115,6 @@ static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
return QGradient::LogicalMode;
}
-/* Returns true if the gradient requires stretch to device...*/
-static inline bool check_gradient(const QBrush &brush)
-{
- return coordinateMode(brush) == QGradient::StretchToDeviceMode;
-}
-
extern bool qHasPixmapTexture(const QBrush &);
static inline bool is_brush_transparent(const QBrush &brush) {
@@ -780,8 +774,8 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
complexXform = !s->matrix.isAffine();
}
- const bool brushXform = (!s->brush.transform().type() == QTransform::TxNone);
- const bool penXform = (!s->pen.brush().transform().type() == QTransform::TxNone);
+ const bool brushXform = (s->brush.transform().type() != QTransform::TxNone);
+ const bool penXform = (s->pen.brush().transform().type() != QTransform::TxNone);
const bool patternXform = patternBrush && (xform || brushXform || penXform);
@@ -1653,7 +1647,7 @@ void QPainter::restore()
//Since we've updated the clip region anyway, pretend that the clip path hasn't changed:
d->state->dirtyFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
- tmp->changeFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
+ tmp->changeFlags &= ~uint(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
tmp->changeFlags |= QPaintEngine::DirtyTransform;
}
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 243c99e671..61a6587233 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -45,6 +45,7 @@
#include <private/qdatabuffer_p.h>
#include <private/qnumeric_p.h>
#include <qmath.h>
+#include <algorithm>
/**
The algorithm is as follows:
@@ -824,7 +825,7 @@ void QWingedEdge::intersectAndAdd()
}
}
- qSort(intersections.data(), intersections.data() + intersections.size());
+ std::sort(intersections.data(), intersections.data() + intersections.size());
int first = m_segments.segmentAt(i).va;
int second = m_segments.segmentAt(i).vb;
@@ -1651,7 +1652,7 @@ bool QPathClipper::doClip(QWingedEdge &list, ClipperMode mode)
for (int i = 0; i < list.vertexCount(); ++i)
y_coords << list.vertex(i)->y;
- qSort(y_coords.begin(), y_coords.end());
+ std::sort(y_coords.begin(), y_coords.end());
y_coords.resize(qRemoveDuplicates(y_coords.begin(), y_coords.end(), fuzzyCompare) - y_coords.begin());
#ifdef QDEBUG_CLIPPER
@@ -1827,7 +1828,7 @@ bool QPathClipper::handleCrossingEdges(QWingedEdge &list, qreal y, ClipperMode m
QVector<QCrossingEdge> crossings = findCrossings(list, y);
Q_ASSERT(!crossings.isEmpty());
- qSort(crossings.begin(), crossings.end());
+ std::sort(crossings.begin(), crossings.end());
int windingA = 0;
int windingB = 0;
diff --git a/src/gui/painting/qpathsimplifier.cpp b/src/gui/painting/qpathsimplifier.cpp
index c65daf0da2..1e9c483ff8 100644
--- a/src/gui/painting/qpathsimplifier.cpp
+++ b/src/gui/painting/qpathsimplifier.cpp
@@ -138,7 +138,6 @@ Fraction fraction(unsigned int n, unsigned int d) {
struct Rational
{
- bool isValid() const { return fraction.isValid(); }
int integer;
Fraction fraction;
};
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index 197d49369e..a7e7d89ec4 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -48,6 +48,8 @@
#include <private/qdatabuffer_p.h>
#include <private/qdrawhelper_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
typedef int Q16Dot16;
@@ -326,7 +328,7 @@ void qScanConvert(QScanConverter &d, T allVertical)
d.m_active.reset();
return;
}
- qSort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), QT_PREPEND_NAMESPACE(topOrder));
+ std::sort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), QT_PREPEND_NAMESPACE(topOrder));
int line = 0;
for (int y = d.m_lines.first().top; y <= d.m_bottom; ++y) {
for (; line < d.m_lines.size() && d.m_lines.at(line).top == y; ++line) {
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 6676d3daa6..2166ae7975 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -108,7 +108,6 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
#endif
m_current_fontengine = fontEngine;
- const int margin = m_current_fontengine->glyphMargin(m_type);
const int padding = glyphPadding();
const int paddingDoubled = padding * 2;
@@ -174,8 +173,6 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
coords.insert(key, c);
continue;
}
- glyph_width += margin * 2 + 4;
- glyph_height += margin * 2 + 4;
// align to 8-bit boundary
if (m_type == QFontEngineGlyphCache::Raster_Mono)
glyph_width = (glyph_width+7)&~7;
@@ -192,7 +189,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
if (listItemCoordinates.isEmpty())
return true;
- rowHeight += margin * 2 + paddingDoubled;
+ rowHeight += paddingDoubled;
if (m_w == 0) {
if (fontEngine->maxCharWidth() <= QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH)
@@ -207,7 +204,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
while (iter != listItemCoordinates.end()) {
Coord c = iter.value();
- m_currentRowHeight = qMax(m_currentRowHeight, c.h + margin * 2);
+ m_currentRowHeight = qMax(m_currentRowHeight, c.h);
if (m_cx + c.w + padding > requiredWidth) {
int new_width = requiredWidth*2;
@@ -219,7 +216,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
// no room on the current line, start new glyph strip
m_cx = padding;
m_cy += m_currentRowHeight + paddingDoubled;
- m_currentRowHeight = c.h + margin * 2; // New row
+ m_currentRowHeight = c.h; // New row
}
}
diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp
index b7b8e919ad..b8f5aa70a9 100644
--- a/src/gui/text/qabstracttextdocumentlayout.cpp
+++ b/src/gui/text/qabstracttextdocumentlayout.cpp
@@ -412,8 +412,6 @@ QAbstractTextDocumentLayout::~QAbstractTextDocumentLayout()
}
/*!
- \fn void QAbstractTextDocumentLayout::registerHandler(int objectType, QObject *component)
-
Registers the given \a component as a handler for items of the given \a objectType.
\note registerHandler() has to be called once for each object type. This
@@ -422,7 +420,7 @@ QAbstractTextDocumentLayout::~QAbstractTextDocumentLayout()
The text document layout does not take ownership of \c component.
*/
-void QAbstractTextDocumentLayout::registerHandler(int formatType, QObject *component)
+void QAbstractTextDocumentLayout::registerHandler(int objectType, QObject *component)
{
Q_D(QAbstractTextDocumentLayout);
@@ -435,7 +433,25 @@ void QAbstractTextDocumentLayout::registerHandler(int formatType, QObject *compo
QTextObjectHandler h;
h.iface = iface;
h.component = component;
- d->handlers.insert(formatType, h);
+ d->handlers.insert(objectType, h);
+}
+
+/*!
+ \since 5.2
+
+ Unregisters the given \a component as a handler for items of the given \a objectType, or
+ any handler if the \a component is not specified.
+*/
+void QAbstractTextDocumentLayout::unregisterHandler(int objectType, QObject *component)
+{
+ Q_D(QAbstractTextDocumentLayout);
+
+ HandlerHash::iterator it = d->handlers.find(objectType);
+ if (it != d->handlers.end() && (!component || component == it->component)) {
+ if (component)
+ disconnect(component, SIGNAL(destroyed(QObject*)), this, SLOT(_q_handlerDestroyed(QObject*)));
+ d->handlers.erase(it);
+ }
}
/*!
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 95733f5da7..4bae631b9c 100644
--- a/src/gui/text/qabstracttextdocumentlayout.h
+++ b/src/gui/text/qabstracttextdocumentlayout.h
@@ -98,6 +98,7 @@ public:
QTextDocument *document() const;
void registerHandler(int objectType, QObject *component);
+ void unregisterHandler(int objectType, QObject *component = 0);
QTextObjectInterface *handlerForObject(int objectType) const;
Q_SIGNALS:
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 54b4629ca0..6da103e931 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -53,9 +53,11 @@
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformfontdatabase.h>
+#include <qpa/qplatformtheme.h>
#include <stdlib.h>
#include <limits.h>
+#include <algorithm>
// #define QFONTDATABASE_DEBUG
@@ -1082,6 +1084,17 @@ QFontDatabase::QFontDatabase()
*/
/*!
+ \enum QFontDatabase::SystemFont
+
+ \value GeneralFont The default system font.
+ \value FixedFont The fixed font that the system recommends.
+ \value TitleFont The system standard font for titles.
+ \value SmallestReadableFont The smallest readable system font.
+
+ \since 5.2
+*/
+
+/*!
Returns a sorted list of the available writing systems. This is
list generated from information about all installed fonts on the
system.
@@ -1107,7 +1120,7 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const
list.append(writingSystem);
}
}
- qSort(list);
+ std::sort(list.begin(), list.end());
return list;
}
@@ -1399,7 +1412,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family,
if (smoothScalable)
return standardSizes();
- qSort(sizes);
+ std::sort(sizes.begin(), sizes.end());
return sizes;
}
@@ -1502,7 +1515,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family,
if (smoothScalable)
return QFontDatabase::standardSizes();
- qSort(sizes);
+ std::sort(sizes.begin(), sizes.end());
return sizes;
}
@@ -2090,6 +2103,43 @@ QStringList QFontDatabase::applicationFontFamilies(int id)
}
/*!
+ \since 5.2
+
+ Returns the most adequate font for a given \a type case for proper integration
+ with the system's look and feel.
+
+ \sa QGuiApplication::font()
+*/
+
+QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
+{
+ const QFont *font = 0;
+ if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
+ switch (type) {
+ case GeneralFont:
+ font = theme->font(QPlatformTheme::SystemFont);
+ break;
+ case FixedFont:
+ font = theme->font(QPlatformTheme::FixedFont);
+ break;
+ case TitleFont:
+ font = theme->font(QPlatformTheme::TitleBarFont);
+ break;
+ case SmallestReadableFont:
+ font = theme->font(QPlatformTheme::MiniFont);
+ break;
+ }
+ }
+
+ if (font)
+ return *font;
+ else if (QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration())
+ return integration->fontDatabase()->defaultFont();
+ else
+ return QFont();
+}
+
+/*!
\fn bool QFontDatabase::removeApplicationFont(int id)
\since 4.2
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 05f1a85f24..bd603c3c4a 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -60,6 +60,7 @@ class Q_GUI_EXPORT QFontDatabase
{
Q_GADGET
Q_ENUMS(WritingSystem)
+ Q_ENUMS(SystemFont)
public:
// do not re-order or delete entries from this enum without updating the
// QPF2 format and makeqpf!!
@@ -106,6 +107,13 @@ public:
WritingSystemsCount
};
+ enum SystemFont {
+ GeneralFont,
+ FixedFont,
+ TitleFont,
+ SmallestReadableFont
+ };
+
static QList<int> standardSizes();
QFontDatabase();
@@ -144,6 +152,8 @@ public:
static bool supportsThreadedFontRendering();
+ static QFont systemFont(SystemFont type);
+
private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 62b99968bc..8e6ad7cd97 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -85,7 +85,7 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &sty
size->handle = handle;
}
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
+void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
{
if (alias.isEmpty())
return;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 1ce70c6d83..9e6b8d6ffd 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -50,6 +50,8 @@
#include <qendian.h>
#include <private/qharfbuzz_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
static inline bool qtransform_equals_no_translate(const QTransform &a, const QTransform &b)
@@ -71,11 +73,16 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr
// Harfbuzz helper functions
+Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t));
+Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));
+
static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft)
{
QFontEngine *fe = (QFontEngine *)font->userData;
- QVarLengthGlyphLayoutArray qglyphs(*numGlyphs);
+ QGlyphLayout qglyphs;
+ qglyphs.numGlyphs = *numGlyphs;
+ qglyphs.glyphs = glyphs;
QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
if (rightToLeft)
@@ -84,28 +91,23 @@ static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint
int nGlyphs = *numGlyphs;
bool result = fe->stringToCMap(reinterpret_cast<const QChar *>(string), length, &qglyphs, &nGlyphs, shaperFlags);
*numGlyphs = nGlyphs;
- if (!result)
- return false;
-
- for (hb_uint32 i = 0; i < *numGlyphs; ++i)
- glyphs[i] = qglyphs.glyphs[i];
- return true;
+ return result;
}
static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags)
{
QFontEngine *fe = (QFontEngine *)font->userData;
- QVarLengthGlyphLayoutArray qglyphs(numGlyphs);
+ QVarLengthArray<QFixed> advances_y(numGlyphs);
- for (hb_uint32 i = 0; i < numGlyphs; ++i)
- qglyphs.glyphs[i] = glyphs[i];
+ QGlyphLayout qglyphs;
+ qglyphs.numGlyphs = numGlyphs;
+ qglyphs.glyphs = const_cast<glyph_t *>(glyphs);
+ qglyphs.advances_x = reinterpret_cast<QFixed *>(advances);
+ qglyphs.advances_y = advances_y.data(); // not used
fe->recalcAdvances(&qglyphs, (flags & HB_ShaperFlag_UseDesignMetrics) ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlags(0));
-
- for (hb_uint32 i = 0; i < numGlyphs; ++i)
- advances[i] = qglyphs.advances_x[i].value();
}
static HB_Bool hb_canRender(HB_Font font, const HB_UChar16 *string, hb_uint32 length)
@@ -143,7 +145,7 @@ int QFontEngine::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFix
Q_UNUSED(xpos)
Q_UNUSED(ypos)
Q_UNUSED(nPoints)
- return HB_Err_Not_Covered;
+ return Err_Not_Covered;
}
static HB_Error hb_getPointInOutline(HB_Font font, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
@@ -203,17 +205,6 @@ QFontEngine::QFontEngine()
fsType = 0;
symbol = false;
- {
- HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
- Q_CHECK_PTR(hbFont);
- memset(hbFont, 0, sizeof(HB_FontRec));
- hbFont->klass = &hb_fontClass;
- hbFont->userData = this;
-
- font_ = (void *)hbFont;
- font_destroy_func = free;
- }
-
glyphFormat = -1;
m_subPixelPositionCount = 0;
@@ -262,8 +253,12 @@ QFixed QFontEngine::underlinePosition() const
void *QFontEngine::harfbuzzFont() const
{
- HB_FontRec *hbFont = (HB_FontRec *)font_;
- if (!hbFont->x_ppem) {
+ if (!font_) {
+ HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
+ Q_CHECK_PTR(hbFont);
+ hbFont->klass = &hb_fontClass;
+ hbFont->userData = const_cast<QFontEngine *>(this);
+
qint64 emSquare = emSquareSize().truncate();
Q_ASSERT(emSquare == emSquareSize().toInt()); // ensure no truncation
if (emSquare == 0)
@@ -273,6 +268,9 @@ void *QFontEngine::harfbuzzFont() const
// same as QFixed(x)/QFixed(emSquare) but without int32 overflow for x
hbFont->x_scale = (((qint64)hbFont->x_ppem << 6) * 0x10000L + (emSquare >> 1)) / emSquare;
hbFont->y_scale = (((qint64)hbFont->y_ppem << 6) * 0x10000L + (emSquare >> 1)) / emSquare;
+
+ font_ = (void *)hbFont;
+ font_destroy_func = free;
}
return font_;
}
@@ -973,7 +971,7 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
}
}
end:
- qSort(kerning_pairs);
+ std::sort(kerning_pairs.begin(), kerning_pairs.end());
// for (int i = 0; i < kerning_pairs.count(); ++i)
// qDebug() << 'i' << i << "left_right" << hex << kerning_pairs.at(i).left_right;
}
@@ -1439,10 +1437,12 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate());
uint ucs4 = surrogate ? QChar::surrogateToUcs4(str[i], str[i+1]) : str[i].unicode();
if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) {
- QGlyphLayoutInstance tmp;
- if (!(flags & GlyphIndicesOnly))
- tmp = glyphs->instance(glyph_pos);
- for (int x=1; x < engines.size(); ++x) {
+ QFixedPoint tmpAdvance;
+ if (!(flags & GlyphIndicesOnly)) {
+ tmpAdvance.x = glyphs->advances_x[glyph_pos];
+ tmpAdvance.y = glyphs->advances_y[glyph_pos];
+ }
+ for (int x = 1, n = qMin(engines.size(), 256); x < n; ++x) {
if (engines.at(x) == 0 && !shouldLoadFontEngineForCharacter(x, ucs4))
continue;
@@ -1455,10 +1455,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
if (engine->type() == Box)
continue;
- if (!(flags & GlyphIndicesOnly)) {
+ if (!(flags & GlyphIndicesOnly))
glyphs->advances_x[glyph_pos] = glyphs->advances_y[glyph_pos] = 0;
- glyphs->offsets[glyph_pos] = QFixedPoint();
- }
int num = 2;
QGlyphLayout offs = glyphs->mid(glyph_pos, num);
engine->stringToCMap(str + i, surrogate ? 2 : 1, &offs, &num, flags);
@@ -1471,8 +1469,10 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
}
// ensure we use metrics from the 1st font when we use the fallback image.
- if (!(flags & GlyphIndicesOnly) && !glyphs->glyphs[glyph_pos])
- glyphs->setInstance(glyph_pos, tmp);
+ if (!(flags & GlyphIndicesOnly) && glyphs->glyphs[glyph_pos] == 0) {
+ glyphs->advances_x[glyph_pos] = tmpAdvance.x;
+ glyphs->advances_y[glyph_pos] = tmpAdvance.y;
+ }
}
if (surrogate)
@@ -1774,22 +1774,27 @@ bool QFontEngineMulti::canRender(const QChar *string, int len)
if (engine(0)->canRender(string, len))
return true;
- QVarLengthGlyphLayoutArray glyphs(len);
int nglyphs = len;
- if (!stringToCMap(string, len, &glyphs, &nglyphs, GlyphIndicesOnly)) {
+
+ QVarLengthArray<glyph_t> glyphs(nglyphs);
+
+ QGlyphLayout g;
+ g.numGlyphs = nglyphs;
+ g.glyphs = glyphs.data();
+ if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly)) {
glyphs.resize(nglyphs);
- stringToCMap(string, len, &glyphs, &nglyphs, GlyphIndicesOnly);
+ g.numGlyphs = nglyphs;
+ g.glyphs = glyphs.data();
+ if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly))
+ Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
}
- bool allExist = true;
for (int i = 0; i < nglyphs; i++) {
- if (!glyphs.glyphs[i]) {
- allExist = false;
- break;
- }
+ if (g.glyphs[i] == 0)
+ return false;
}
- return allExist;
+ return true;
}
/* Implement alphaMapForGlyph() which is called by Lighthouse/Windows code.
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 7b4925a9c8..cad9b02f41 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -46,8 +46,6 @@
#include "qfontengine_ft_p.h"
#include "private/qimage_p.h"
-#include <private/qharfbuzz_p.h>
-
#ifndef QT_NO_FREETYPE
#include "qfile.h"
@@ -118,24 +116,6 @@ QT_BEGIN_NAMESPACE
#define TRUNC(x) ((x) >> 6)
#define ROUND(x) (((x)+32) & -64)
-static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)
-{
-#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) > 20103
- FT_Face face = (FT_Face)font;
- FT_ULong ftlen = *length;
- FT_Error error = 0;
-
- if ( !FT_IS_SFNT(face) )
- return HB_Err_Invalid_Argument;
-
- error = FT_Load_Sfnt_Table(face, tableTag, 0, buffer, &ftlen);
- *length = ftlen;
- return (HB_Error)error;
-#else
- return HB_Err_Invalid_Argument;
-#endif
-}
-
// -------------------------- Freetype support ------------------------------
class QtFreetypeData
@@ -191,19 +171,19 @@ int QFreetypeFace::getPointInOutline(glyph_t glyph, int flags, quint32 point, QF
return error;
if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
- return HB_Err_Invalid_SubTable;
+ return Err_Invalid_SubTable;
*nPoints = face->glyph->outline.n_points;
if (!(*nPoints))
- return HB_Err_Ok;
+ return Err_Ok;
if (point > *nPoints)
- return HB_Err_Invalid_SubTable;
+ return Err_Invalid_SubTable;
*xpos = QFixed::fromFixed(face->glyph->outline.points[point].x);
*ypos = QFixed::fromFixed(face->glyph->outline.points[point].y);
- return HB_Err_Ok;
+ return Err_Ok;
}
extern QByteArray qt_fontdata_from_index(int);
@@ -260,11 +240,8 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
}
newFreetype->face = face;
- HB_Face hbFace = qHBNewFace(face, hb_getSFntTable);
- Q_CHECK_PTR(hbFace);
- if (hbFace->font_for_init != 0)
- hbFace = qHBLoadFace(hbFace);
- newFreetype->hbFace = (void *)hbFace;
+ newFreetype->hbFace = 0;
+ newFreetype->hbFace_destroy_func = 0;
newFreetype->ref.store(1);
newFreetype->xsize = 0;
@@ -319,7 +296,10 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id)
{
QtFreetypeData *freetypeData = qt_getFreetypeData();
if (!ref.deref()) {
- qHBFreeFace((HB_Face)hbFace);
+ if (hbFace && hbFace_destroy_func) {
+ hbFace_destroy_func(hbFace);
+ hbFace = 0;
+ }
FT_Done_Face(face);
if(freetypeData->faces.contains(face_id))
freetypeData->faces.take(face_id);
@@ -695,8 +675,6 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
if (FT_Get_PS_Font_Info(freetype->face, &psrec) == FT_Err_Ok) {
symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive));
}
- // #####
- ((HB_Face)freetype->hbFace)->isSymbolFont = symbol;
lbearing = rbearing = SHRT_MIN;
freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing);
@@ -734,18 +712,6 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
if (line_thickness < 1)
line_thickness = 1;
- HB_FontRec *hbFont = (HB_FontRec *)font_;
- hbFont->x_ppem = face->size->metrics.x_ppem;
- hbFont->y_ppem = face->size->metrics.y_ppem;
- hbFont->x_scale = face->size->metrics.x_scale;
- hbFont->y_scale = face->size->metrics.y_scale;
-
- // ###
- if (face_ && face_destroy_func)
- face_destroy_func(face_);
- face_ = freetype->hbFace;
- face_destroy_func = 0; // we share the face in QFreeTypeFace, don't let ~QFontEngine delete it
-
metrics = face->size->metrics;
/*
@@ -773,6 +739,15 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
fontDef.styleName = QString::fromUtf8(face->style_name);
+ if (!freetype->hbFace) {
+ freetype->hbFace = harfbuzzFace();
+ freetype->hbFace_destroy_func = face_destroy_func;
+ } else {
+ Q_ASSERT(!face_);
+ face_ = freetype->hbFace;
+ }
+ face_destroy_func = 0; // we share the HB face in QFreeTypeFace, so do not let ~QFontEngine() destroy it
+
unlockFace();
fsType = freetype->fsType();
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index bd4c855b91..084ef6cea3 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -75,11 +75,12 @@ class QFontEngineFTRawFont;
class QFontconfigDatabase;
/*
- * This struct represents one font file on disk (like Arial.ttf) and is shared between all the font engines
+ * This class represents one font file on disk (like Arial.ttf) and is shared between all the font engines
* that show this font file (at different pixel sizes).
*/
-struct QFreetypeFace
+class QFreetypeFace
{
+public:
void computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing);
QFontEngine::Properties properties() const;
bool getSfntTable(uint tag, uchar *buffer, uint *length) const;
@@ -99,7 +100,6 @@ struct QFreetypeFace
}
FT_Face face;
- void *hbFace;
int xsize; // 26.6
int ysize; // 26.6
FT_Matrix matrix;
@@ -124,6 +124,9 @@ private:
QAtomicInt ref;
QMutex _lock;
QByteArray fontData;
+
+ void *hbFace;
+ qt_destroy_func_t hbFace_destroy_func;
};
// If this is exported this breaks compilation of the windows
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 855f0099ff..4427000d03 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -75,6 +75,15 @@ struct QGlyphLayout;
((quint32)(ch4)) \
)
+// ### this only used in getPointInOutline(), refactor it and then remove these magic numbers
+enum HB_Compat_Error {
+ Err_Ok = 0x0000,
+ Err_Not_Covered = 0xFFFF,
+ Err_Invalid_Argument = 0x1A66,
+ Err_Invalid_SubTable_Format = 0x157F,
+ Err_Invalid_SubTable = 0x1570
+};
+
typedef void (*qt_destroy_func_t) (void *user_data);
class Q_GUI_EXPORT QFontEngine : public QObject
diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
index def671c62f..78bc3f871a 100644
--- a/src/gui/text/qfontengine_qpf.cpp
+++ b/src/gui/text/qfontengine_qpf.cpp
@@ -50,7 +50,6 @@
#include <QtCore/qbuffer.h>
#if !defined(QT_NO_FREETYPE)
#include "private/qfontengine_ft_p.h"
-#include <private/qharfbuzz_p.h>
#endif
#include "private/qcore_unix_p.h" // overrides QT_OPEN
@@ -858,7 +857,7 @@ void QFontEngineQPF::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags)
int QFontEngineQPF::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints)
{
if (!freetype)
- return HB_Err_Not_Covered;
+ return Err_Not_Covered;
lockFace();
int result = freetype->getPointInOutline(glyph, flags, point, xpos, ypos, nPoints);
unlockFace();
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index 3c39272d11..01ae5888e2 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -48,6 +48,8 @@
#include "qfontsubset_agl.cpp"
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
// This map is used for symbol fonts to get the correct glyph names for the latin range
@@ -998,7 +1000,7 @@ static QList<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QLis
{
const int max_size_small = 65536*2;
QList<QTtfGlyph> glyphs = _glyphs;
- qSort(glyphs);
+ std::sort(glyphs.begin(), glyphs.end());
Q_ASSERT(tables.maxp.numGlyphs == glyphs.at(glyphs.size()-1).index + 1);
int nGlyphs = tables.maxp.numGlyphs;
@@ -1076,7 +1078,7 @@ static QByteArray bindFont(const QList<QTtfTable>& _tables)
{
QList<QTtfTable> tables = _tables;
- qSort(tables);
+ std::sort(tables.begin(), tables.end());
QByteArray font;
const int header_size = sizeof(qint32) + 4*sizeof(quint16);
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 4399aff9da..293535a2e1 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -53,6 +53,8 @@ extern void qt_registerFont(const QString &familyname, const QString &stylename,
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *hanlde);
+void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
+
/*!
\fn void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
@@ -517,6 +519,17 @@ QSupportedWritingSystems QPlatformFontDatabase::writingSystemsFromTrueTypeBits(q
}
/*!
+ Helper function that register the \a alias for the \a familyName.
+
+ \since 5.2
+*/
+
+void QPlatformFontDatabase::registerAliasToFontFamily(const QString &familyName, const QString &alias)
+{
+ qt_registerAliasToFontFamily(familyName, alias);
+}
+
+/*!
\class QPlatformFontDatabase
\since 5.0
\internal
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 6e53eba98b..6053f11051 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -122,6 +122,8 @@ public:
QFont::Style style, QFont::Stretch stretch, bool antialiased,
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *handle);
+
+ static void registerAliasToFontFamily(const QString &familyName, const QString &alias);
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 9d9cbcf6c1..a85e9c86c9 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -260,7 +260,7 @@ public:
void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style);
Q_SIGNALS:
- void contentsChange(int from, int charsRemoves, int charsAdded);
+ void contentsChange(int from, int charsRemoved, int charsAdded);
void contentsChanged();
void undoAvailable(bool);
void redoAvailable(bool);
diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp
index b4a4a07c42..a294bceacc 100644
--- a/src/gui/text/qtextdocumentwriter.cpp
+++ b/src/gui/text/qtextdocumentwriter.cpp
@@ -52,6 +52,8 @@
#include "qtextdocumentfragment_p.h"
#include "qtextodfwriter_p.h"
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
class QTextDocumentWriterPrivate
@@ -366,7 +368,7 @@ QList<QByteArray> QTextDocumentWriter::supportedDocumentFormats()
answer << "ODF";
#endif // QT_NO_TEXTODFWRITER
- qSort(answer);
+ std::sort(answer.begin(), answer.end());
return answer;
}
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 2fa7f0232d..7a12b241e8 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -59,9 +59,9 @@
#include <algorithm>
#include <stdlib.h>
+#ifndef QT_NO_RAWFONT
#include "qfontengine_qpa_p.h"
-
-#include <private/qharfbuzz_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -838,21 +838,6 @@ void QTextEngine::bidiReorder(int numItems, const quint8 *levels, int *visualOrd
#endif
}
-// ask the font engine to find out which glyphs (as an index in the specific font) to use for the text in one item.
-static bool stringToGlyphs(HB_ShaperItem *item, QGlyphLayout *glyphs, QFontEngine *fontEngine)
-{
- int nGlyphs = item->num_glyphs;
-
- QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (item->item.bidiLevel % 2)
- shaperFlags |= QFontEngine::RightToLeft;
-
- bool result = fontEngine->stringToCMap(reinterpret_cast<const QChar *>(item->string + item->item.pos), item->item.length, glyphs, &nGlyphs, shaperFlags);
- item->num_glyphs = nGlyphs;
- glyphs->numGlyphs = nGlyphs;
- return result;
-}
-
// shape all the items that intersect with the line, taking tab widths into account to find out what text actually fits in the line.
void QTextEngine::shapeLine(const QScriptLine &line)
{
@@ -892,19 +877,48 @@ void QTextEngine::shapeText(int item) const
if (si.num_glyphs)
return;
- shapeTextWithHarfbuzz(item);
-
si.width = 0;
+ si.glyph_data_offset = layoutData->used;
- if (!si.num_glyphs)
- return;
- QGlyphLayout glyphs = shapedGlyphs(&si);
+ const ushort *string = reinterpret_cast<const ushort *>(layoutData->string.constData()) + si.position;
+ const int itemLength = length(item);
+
+ if (!ensureSpace(itemLength))
+ return; // ### report OOM error somehow
+
+ QString casedString;
+ if (si.analysis.flags && si.analysis.flags <= QScriptAnalysis::SmallCaps) {
+ casedString.resize(itemLength);
+ ushort *uc = reinterpret_cast<ushort *>(casedString.data());
+ for (int i = 0; i < itemLength; ++i) {
+ uint ucs4 = string[i];
+ if (QChar::isHighSurrogate(ucs4) && i + 1 < itemLength) {
+ uint low = string[i + 1];
+ if (QChar::isLowSurrogate(low)) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, low);
+ ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
+ : QChar::toUpper(ucs4);
+ // high part never changes in simple casing
+ uc[i] = QChar::lowSurrogate(ucs4);
+ }
+ } else {
+ uc[i] = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
+ : QChar::toUpper(ucs4);
+ }
+ }
+ string = reinterpret_cast<const ushort *>(casedString.constData());
+ }
+ QFontEngine *fontEngine = this->fontEngine(si, &si.ascent, &si.descent, &si.leading);
+
+ bool kerningEnabled;
bool letterSpacingIsAbsolute;
QFixed letterSpacing, wordSpacing;
#ifndef QT_NO_RAWFONT
if (useRawFont) {
QTextCharFormat f = format(&si);
+ kerningEnabled = f.fontKerning();
wordSpacing = QFixed::fromReal(f.fontWordSpacing());
letterSpacing = QFixed::fromReal(f.fontLetterSpacing());
letterSpacingIsAbsolute = true;
@@ -912,6 +926,7 @@ void QTextEngine::shapeText(int item) const
#endif
{
QFont font = this->font(si);
+ kerningEnabled = font.d->kerning;
letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
letterSpacing = font.d->letterSpacing;
wordSpacing = font.d->wordSpacing;
@@ -920,6 +935,13 @@ void QTextEngine::shapeText(int item) const
letterSpacing *= font.d->dpi / qt_defaultDpiY();
}
+ si.num_glyphs = shapeTextWithHarfbuzz(si, string, itemLength, fontEngine, kerningEnabled);
+ if (!si.num_glyphs)
+ return; // ### report shaping errors somehow
+ layoutData->used += si.num_glyphs;
+
+ QGlyphLayout glyphs = shapedGlyphs(&si);
+
if (letterSpacing != 0) {
for (int i = 1; i < si.num_glyphs; ++i) {
if (glyphs.attributes[i].clusterStart) {
@@ -940,12 +962,12 @@ void QTextEngine::shapeText(int item) const
}
if (wordSpacing != 0) {
for (int i = 0; i < si.num_glyphs; ++i) {
- if (glyphs.attributes[i].justification == HB_Space
- || glyphs.attributes[i].justification == HB_Arabic_Space) {
+ if (glyphs.attributes[i].justification == QGlyphAttributes::Space
+ || glyphs.attributes[i].justification == QGlyphAttributes::Arabic_Space) {
// word spacing only gets added once to a consecutive run of spaces (see CSS spec)
if (i + 1 == si.num_glyphs
- ||(glyphs.attributes[i+1].justification != HB_Space
- && glyphs.attributes[i+1].justification != HB_Arabic_Space))
+ ||(glyphs.attributes[i+1].justification != QGlyphAttributes::Space
+ && glyphs.attributes[i+1].justification != QGlyphAttributes::Arabic_Space))
glyphs.advances_x[i] += wordSpacing;
}
}
@@ -955,14 +977,6 @@ void QTextEngine::shapeText(int item) const
si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
}
-static inline bool hasCaseChange(const QScriptItem &si)
-{
- return si.analysis.flags == QScriptAnalysis::SmallCaps ||
- si.analysis.flags == QScriptAnalysis::Uppercase ||
- si.analysis.flags == QScriptAnalysis::Lowercase;
-}
-
-
static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
{
if (num > 0 && destination.glyphs != source.glyphs) {
@@ -973,84 +987,60 @@ static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLa
}
}
+QT_BEGIN_INCLUDE_NAMESPACE
+
+#include <private/qharfbuzz_p.h>
+
+QT_END_INCLUDE_NAMESPACE
+
Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t));
Q_STATIC_ASSERT(sizeof(HB_GlyphAttributes) == sizeof(QGlyphAttributes));
Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));
Q_STATIC_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint));
-/// take the item from layoutData->items and
-void QTextEngine::shapeTextWithHarfbuzz(int item) const
+// ask the font engine to find out which glyphs (as an index in the specific font) to use for the text in one item.
+static bool stringToGlyphs(HB_ShaperItem *item, QGlyphLayout *glyphs, QFontEngine *fontEngine)
{
- QScriptItem &si = layoutData->items[item];
-
- si.glyph_data_offset = layoutData->used;
+ int nGlyphs = item->num_glyphs;
- QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
+ QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
+ if (item->item.bidiLevel % 2)
+ shaperFlags |= QFontEngine::RightToLeft;
- bool kerningEnabled;
-#ifndef QT_NO_RAWFONT
- if (useRawFont) {
- QTextCharFormat f = format(&si);
- kerningEnabled = f.fontKerning();
- } else
-#endif
- kerningEnabled = this->font(si).d->kerning;
+ bool result = fontEngine->stringToCMap(reinterpret_cast<const QChar *>(item->string + item->item.pos), item->item.length, glyphs, &nGlyphs, shaperFlags);
+ item->num_glyphs = nGlyphs;
+ glyphs->numGlyphs = nGlyphs;
+ return result;
+}
+int QTextEngine::shapeTextWithHarfbuzz(QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, bool kerningEnabled) const
+{
HB_ShaperItem entire_shaper_item;
memset(&entire_shaper_item, 0, sizeof(entire_shaper_item));
- entire_shaper_item.string = reinterpret_cast<const HB_UChar16 *>(layoutData->string.constData());
- entire_shaper_item.stringLength = layoutData->string.length();
+ entire_shaper_item.string = reinterpret_cast<const HB_UChar16 *>(string);
+ entire_shaper_item.stringLength = itemLength;
entire_shaper_item.item.script = script_to_hbscript(si.analysis.script);
- entire_shaper_item.item.pos = si.position;
- entire_shaper_item.item.length = length(item);
+ entire_shaper_item.item.pos = 0;
+ entire_shaper_item.item.length = itemLength;
entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel;
- QVarLengthArray<HB_UChar16, 256> casedString;
- if (hasCaseChange(si)) {
- if (casedString.size() < static_cast<int>(entire_shaper_item.item.length))
- casedString.resize(entire_shaper_item.item.length);
- HB_UChar16 *uc = casedString.data();
- for (uint i = 0; i < entire_shaper_item.item.length; ++i) {
- uint ucs4 = entire_shaper_item.string[si.position + i];
- if (QChar::isHighSurrogate(ucs4)) {
- uc[i] = ucs4; // high part never changes in simple casing
- if (i + 1 < entire_shaper_item.item.length) {
- ushort low = entire_shaper_item.string[si.position + i + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
- : QChar::toUpper(ucs4);
- uc[++i] = QChar::lowSurrogate(ucs4);
- }
- }
- } else {
- uc[i] = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
- : QChar::toUpper(ucs4);
- }
- }
- entire_shaper_item.item.pos = 0;
- entire_shaper_item.string = uc;
- entire_shaper_item.stringLength = entire_shaper_item.item.length;
- }
-
entire_shaper_item.shaperFlags = 0;
if (!kerningEnabled)
entire_shaper_item.shaperFlags |= HB_ShaperFlag_NoKerning;
if (option.useDesignMetrics())
entire_shaper_item.shaperFlags |= HB_ShaperFlag_UseDesignMetrics;
- entire_shaper_item.num_glyphs = qMax(layoutData->glyphLayout.numGlyphs - layoutData->used, int(entire_shaper_item.item.length));
- if (!ensureSpace(entire_shaper_item.num_glyphs))
- return;
+ entire_shaper_item.num_glyphs = itemLength;
+
QGlyphLayout initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
- if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
+ if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, fontEngine)) {
if (!ensureSpace(entire_shaper_item.num_glyphs))
- return;
+ return 0;
initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
- if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
+ if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, fontEngine)) {
// ############ if this happens there's a bug in the fontengine
- return;
+ return 0;
}
}
@@ -1060,7 +1050,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
itemBoundaries[0] = entire_shaper_item.item.pos;
itemBoundaries[1] = 0;
- if (font->type() == QFontEngine::Multi) {
+ if (fontEngine->type() == QFontEngine::Multi) {
uint lastEngine = 0;
int charIdx = entire_shaper_item.item.pos;
const int stringEnd = charIdx + entire_shaper_item.item.length;
@@ -1099,18 +1089,17 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
if (shaper_item.num_glyphs < shaper_item.item.length)
shaper_item.num_glyphs = shaper_item.item.length;
- QFontEngine *actualFontEngine = font;
+ QFontEngine *actualFontEngine = fontEngine;
uint engineIdx = 0;
- if (font->type() == QFontEngine::Multi) {
+ if (fontEngine->type() == QFontEngine::Multi) {
engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24);
- actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
+ actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
+ si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
+ si.descent = qMax(actualFontEngine->descent(), si.descent);
+ si.leading = qMax(actualFontEngine->leading(), si.leading);
}
- si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
- si.descent = qMax(actualFontEngine->descent(), si.descent);
- si.leading = qMax(actualFontEngine->leading(), si.leading);
-
shaper_item.font = (HB_Font)actualFontEngine->harfbuzzFont();
shaper_item.face = (HB_Face)actualFontEngine->harfbuzzFace();
@@ -1120,7 +1109,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
do {
if (!ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs))
- return;
+ return 0;
const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
if (shaper_item.num_glyphs > shaper_item.item.length)
@@ -1137,8 +1126,6 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
}
shaper_item.log_clusters = logClusters(&si) + shaper_item.item.pos - entire_shaper_item.item.pos;
-
-// qDebug(" .. num_glyphs=%d, used=%d, item.num_glyphs=%d", num_glyphs, used, shaper_item.num_glyphs);
} while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz.
QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs);
@@ -1158,10 +1145,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
glyph_pos += shaper_item.num_glyphs;
}
-// qDebug(" -> item: script=%d num_glyphs=%d", shaper_item.script, shaper_item.num_glyphs);
- si.num_glyphs = glyph_pos;
-
- layoutData->used += si.num_glyphs;
+ return glyph_pos;
}
void QTextEngine::init(QTextEngine *e)
@@ -1821,7 +1805,7 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph,
point->type = type;
point->glyph = glyph;
- if (type >= HB_Arabic_Normal) {
+ if (type >= QGlyphAttributes::Arabic_Normal) {
QChar ch(0x640); // Kashida character
QGlyphLayoutArray<8> glyphs;
int nglyphs = 7;
@@ -1829,7 +1813,7 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph,
if (glyphs.glyphs[0] && glyphs.advances_x[0] != 0) {
point->kashidaWidth = glyphs.advances_x[0];
} else {
- point->type = HB_NoJustification;
+ point->type = QGlyphAttributes::NoJustification;
point->kashidaWidth = 0;
}
}
@@ -1897,7 +1881,7 @@ void QTextEngine::justify(const QScriptLine &line)
for (int i = 0; i < nItems; ++i) {
QScriptItem &si = layoutData->items[firstItem + i];
- int kashida_type = HB_Arabic_Normal;
+ int kashida_type = QGlyphAttributes::Arabic_Normal;
int kashida_pos = -1;
int start = qMax(line.from - si.position, 0);
@@ -1921,11 +1905,11 @@ void QTextEngine::justify(const QScriptLine &line)
int justification = g.attributes[i].justification;
switch(justification) {
- case HB_NoJustification:
+ case QGlyphAttributes::NoJustification:
break;
- case HB_Space :
+ case QGlyphAttributes::Space :
// fall through
- case HB_Arabic_Space :
+ case QGlyphAttributes::Arabic_Space :
if (kashida_pos >= 0) {
// qDebug("kashida position at %d in word", kashida_pos);
set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si));
@@ -1936,19 +1920,19 @@ void QTextEngine::justify(const QScriptLine &line)
}
}
kashida_pos = -1;
- kashida_type = HB_Arabic_Normal;
+ kashida_type = QGlyphAttributes::Arabic_Normal;
// fall through
- case HB_Character :
+ case QGlyphAttributes::Character :
set(&justificationPoints[nPoints++], justification, g.mid(i), fontEngine(si));
maxJustify = qMax(maxJustify, justification);
break;
- case HB_Arabic_Normal :
- case HB_Arabic_Waw :
- case HB_Arabic_BaRa :
- case HB_Arabic_Alef :
- case HB_Arabic_HaaDal :
- case HB_Arabic_Seen :
- case HB_Arabic_Kashida :
+ case QGlyphAttributes::Arabic_Normal :
+ case QGlyphAttributes::Arabic_Waw :
+ case QGlyphAttributes::Arabic_BaRa :
+ case QGlyphAttributes::Arabic_Alef :
+ case QGlyphAttributes::Arabic_HaaDal :
+ case QGlyphAttributes::Arabic_Seen :
+ case QGlyphAttributes::Arabic_Kashida :
if (justification >= kashida_type) {
kashida_pos = i;
kashida_type = justification;
@@ -1977,9 +1961,9 @@ void QTextEngine::justify(const QScriptLine &line)
// qDebug(" minKashida=%f, need=%f", minKashida.toReal(), need.toReal());
// distribute in priority order
- if (maxJustify >= HB_Arabic_Normal) {
+ if (maxJustify >= QGlyphAttributes::Arabic_Normal) {
while (need >= minKashida) {
- for (int type = maxJustify; need >= minKashida && type >= HB_Arabic_Normal; --type) {
+ for (int type = maxJustify; need >= minKashida && type >= QGlyphAttributes::Arabic_Normal; --type) {
for (int i = 0; need >= minKashida && i < nPoints; ++i) {
if (justificationPoints[i].type == type && justificationPoints[i].kashidaWidth <= need) {
justificationPoints[i].glyph.justifications->nKashidas++;
@@ -1996,7 +1980,7 @@ void QTextEngine::justify(const QScriptLine &line)
if (!need)
goto end;
- maxJustify = qMin(maxJustify, (int)HB_Space);
+ maxJustify = qMin(maxJustify, int(QGlyphAttributes::Space));
for (int type = maxJustify; need != 0 && type > 0; --type) {
int n = 0;
for (int i = 0; i < nPoints; ++i) {
@@ -2438,12 +2422,13 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
const int end = si.position + length(&si);
for (int i = si.position; i < end - 1; ++i) {
- if (layoutData->string.at(i) == QLatin1Char('&')) {
+ if (layoutData->string.at(i) == QLatin1Char('&')
+ && !attributes[i + 1].whiteSpace && attributes[i + 1].graphemeBoundary) {
const int gp = logClusters[i - si.position];
glyphs.attributes[gp].dontPrint = true;
- attributes[i + 1].graphemeBoundary = false;
- attributes[i + 1].lineBreak = false;
- attributes[i + 1].whiteSpace = false;
+ // emulate grapheme cluster
+ attributes[i] = attributes[i + 1];
+ memset(attributes + i + 1, 0, sizeof(QCharAttributes));
if (layoutData->string.at(i + 1) == QLatin1Char('&'))
++i;
}
@@ -2596,7 +2581,6 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
namespace {
struct QScriptItemComparator {
- bool operator()(const QScriptItem &a, const QScriptItem &b) { return a.position < b.position; }
bool operator()(int p, const QScriptItem &b) { return p < b.position; }
#if defined(Q_CC_MSVC) && _MSC_VER < 1600
//The STL implementation of MSVC 2008 requires the definition
@@ -2786,10 +2770,10 @@ void QTextEngine::resolveAdditionalFormats() const
addFormatSortedByStart.append(i);
}
QVarLengthArray<int, 64> addFormatSortedByEnd = addFormatSortedByStart;
- qSort(addFormatSortedByStart.begin(), addFormatSortedByStart.end(),
- FormatRangeComparatorByStart(specialData->addFormats));
- qSort(addFormatSortedByEnd.begin(), addFormatSortedByEnd.end(),
- FormatRangeComparatorByEnd(specialData->addFormats));
+ std::sort(addFormatSortedByStart.begin(), addFormatSortedByStart.end(),
+ FormatRangeComparatorByStart(specialData->addFormats));
+ std::sort(addFormatSortedByEnd.begin(), addFormatSortedByEnd.end(),
+ FormatRangeComparatorByEnd(specialData->addFormats));
QVarLengthArray<int, 16> currentFormats;
const int *startIt = addFormatSortedByStart.constBegin();
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index ec7f7407b2..b3ab9a42d8 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -96,6 +96,20 @@ typedef quint8 q_hb_bitfield;
#endif
typedef struct {
+ typedef enum {
+ NoJustification= 0, /* Justification can't be applied after this glyph */
+ Arabic_Space = 1, /* This glyph represents a space inside arabic text */
+ Character = 2, /* Inter-character justification point follows this glyph */
+ Space = 4, /* This glyph represents a blank outside an Arabic run */
+ Arabic_Normal = 7, /* Normal Middle-Of-Word glyph that connects to the right (begin) */
+ Arabic_Waw = 8, /* Next character is final form of Waw/Ain/Qaf/Fa */
+ Arabic_BaRa = 9, /* Next two chars are Ba + Ra/Ya/AlefMaksura */
+ Arabic_Alef = 10, /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */
+ Arabic_HaaDal = 11, /* Next character is final form of Haa/Dal/Taa Marbutah */
+ Arabic_Seen = 12, /* Initial or Medial form Of Seen/Sad */
+ Arabic_Kashida = 13 /* Kashida(U+640) in middle of word */
+ } JustificationClass;
+
q_hb_bitfield justification :4; /* Justification class */
q_hb_bitfield clusterStart :1; /* First glyph of representation of cluster */
q_hb_bitfield mark :1; /* needs to be positioned around base char */
@@ -174,15 +188,6 @@ struct QGlyphJustification
};
Q_DECLARE_TYPEINFO(QGlyphJustification, Q_PRIMITIVE_TYPE);
-struct QGlyphLayoutInstance
-{
- QFixedPoint offset;
- QFixedPoint advance;
- glyph_t glyph;
- QGlyphJustification justification;
- QGlyphAttributes attributes;
-};
-
struct QGlyphLayout
{
// init to 0 not needed, done when shaping
@@ -237,28 +242,6 @@ struct QGlyphLayout
inline QFixed effectiveAdvance(int item) const
{ return (advances_x[item] + QFixed::fromFixed(justifications[item].space_18d6)) * !attributes[item].dontPrint; }
- inline QGlyphLayoutInstance instance(int position) const {
- QGlyphLayoutInstance g;
- g.offset.x = offsets[position].x;
- g.offset.y = offsets[position].y;
- g.glyph = glyphs[position];
- g.advance.x = advances_x[position];
- g.advance.y = advances_y[position];
- g.justification = justifications[position];
- g.attributes = attributes[position];
- return g;
- }
-
- inline void setInstance(int position, const QGlyphLayoutInstance &g) {
- offsets[position].x = g.offset.x;
- offsets[position].y = g.offset.y;
- glyphs[position] = g.glyph;
- advances_x[position] = g.advance.x;
- advances_y[position] = g.advance.y;
- justifications[position] = g.justification;
- attributes[position] = g.attributes;
- }
-
inline void clear(int first = 0, int last = -1) {
if (last == -1)
last = numGlyphs;
@@ -685,7 +668,7 @@ private:
void setBoundary(int strPos) const;
void addRequiredBoundaries() const;
void shapeText(int item) const;
- void shapeTextWithHarfbuzz(int item) const;
+ int shapeTextWithHarfbuzz(QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, bool kerningEnabled) const;
void splitItem(int item, int pos) const;
int endOfLine(int lineNum);
diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp
index 173f825b23..a77e1a643c 100644
--- a/src/network/access/qftp.cpp
+++ b/src/network/access/qftp.cpp
@@ -1042,18 +1042,10 @@ bool QFtpPI::processReply()
if (static_cast<signed char>(replyCode[0]) < 0 || replyCode[0] > 5)
state = Failure;
else
-#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
- {
- // work around a crash on 64 bit gcc IRIX
- State *t = (State *) table;
- state = t[replyCode[0] - 1];
- }
-#else
if (replyCodeInt == 202)
state = Failure;
else
state = table[replyCode[0] - 1];
-#endif
break;
default:
// ignore unrequested message
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index a279990f4c..c3e3716b26 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -85,6 +85,7 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
+ , preConnectRequests(0)
{
channels = new QHttpNetworkConnectionChannel[channelCount];
}
@@ -96,6 +97,7 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCoun
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
+ , preConnectRequests(0)
{
channels = new QHttpNetworkConnectionChannel[channelCount];
}
@@ -541,6 +543,9 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
reply->d_func()->connectionChannel = &channels[0]; // will have the correct one set later
HttpMessagePair pair = qMakePair(request, reply);
+ if (request.isPreConnect())
+ preConnectRequests++;
+
switch (request.priority()) {
case QHttpNetworkRequest::HighPriority:
highPriorityQueue.prepend(pair);
@@ -925,13 +930,24 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
// If there is not already any connected channels we need to connect a new one.
// We do not pair the channel with the request until we know if it is
// connected or not. This is to reuse connected channels before we connect new once.
- int queuedRequest = highPriorityQueue.count() + lowPriorityQueue.count();
- for (int i = 0; i < channelCount; ++i) {
+ int queuedRequests = highPriorityQueue.count() + lowPriorityQueue.count();
+
+ // in case we have in-flight preconnect requests and normal requests,
+ // we only need one socket for each (preconnect, normal request) pair
+ int neededOpenChannels = queuedRequests;
+ if (preConnectRequests > 0) {
+ int normalRequests = queuedRequests - preConnectRequests;
+ neededOpenChannels = qMax(normalRequests, preConnectRequests);
+ }
+ for (int i = 0; i < channelCount && neededOpenChannels > 0; ++i) {
bool connectChannel = false;
if (channels[i].socket) {
- if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) || (channels[i].socket->state() == QAbstractSocket::HostLookupState))
- queuedRequest--;
- if ( queuedRequest <=0 )
+ if ((channels[i].socket->state() == QAbstractSocket::ConnectingState)
+ || (channels[i].socket->state() == QAbstractSocket::HostLookupState)
+ || channels[i].pendingEncrypt) // pendingEncrypt == "EncryptingState"
+ neededOpenChannels--;
+
+ if (neededOpenChannels <= 0)
break;
if (!channels[i].reply && !channels[i].isSocketBusy() && (channels[i].socket->state() == QAbstractSocket::UnconnectedState))
connectChannel = true;
@@ -945,11 +961,8 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
else if (networkLayerState == IPv6)
channels[i].networkLayerPreference = QAbstractSocket::IPv6Protocol;
channels[i].ensureConnection();
- queuedRequest--;
+ neededOpenChannels--;
}
-
- if ( queuedRequest <=0 )
- break;
}
}
@@ -1270,6 +1283,11 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int
#endif //QT_NO_SSL
+void QHttpNetworkConnection::preConnectFinished()
+{
+ d_func()->preConnectRequests--;
+}
+
#ifndef QT_NO_NETWORKPROXY
// only called from QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired, not
// from QHttpNetworkConnectionChannel::handleAuthenticationChallenge
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 956499ddab..c54250f6ed 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -131,6 +131,8 @@ public:
void setSslContext(QSharedPointer<QSslContext> context);
#endif
+ void preConnectFinished();
+
private:
Q_DECLARE_PRIVATE(QHttpNetworkConnection)
Q_DISABLE_COPY(QHttpNetworkConnection)
@@ -239,6 +241,8 @@ public:
QList<HttpMessagePair> highPriorityQueue;
QList<HttpMessagePair> lowPriorityQueue;
+ int preConnectRequests;
+
#ifndef QT_NO_SSL
QSharedPointer<QSslContext> sslContext;
#endif
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index e14f426583..6e61eea5a4 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -183,6 +183,9 @@ void QHttpNetworkConnectionChannel::close()
else
state = QHttpNetworkConnectionChannel::ClosingState;
+ // pendingEncrypt must only be true in between connected and encrypted states
+ pendingEncrypt = false;
+
if (socket)
socket->close();
}
@@ -205,6 +208,17 @@ bool QHttpNetworkConnectionChannel::sendRequest()
// _q_connected or _q_encrypted
return false;
}
+ QString scheme = request.url().scheme();
+ if (scheme == QLatin1String("preconnect-http")
+ || scheme == QLatin1String("preconnect-https")) {
+ state = QHttpNetworkConnectionChannel::IdleState;
+ reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
+ allDone();
+ connection->preConnectFinished(); // will only decrease the counter
+ reply = 0; // so we can reuse this channel
+ return true; // we have a working connection and are done
+ }
+
written = 0; // excluding the header
bytesTotal = 0;
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index eb8a8869cc..1b9e1f5a53 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -290,6 +290,11 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
#endif
{
+ QString scheme = newUrl.scheme();
+ if (scheme == QLatin1String("preconnect-http")
+ || scheme == QLatin1String("preconnect-https"))
+ // make sure we do not close the socket after preconnecting
+ connectionCloseEnabled = false;
}
QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate()
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index e5b2eced99..d9f9b555d7 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -49,7 +49,8 @@ QT_BEGIN_NAMESPACE
QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
: QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(0),
- autoDecompress(false), pipeliningAllowed(false), withCredentials(true)
+ autoDecompress(false), pipeliningAllowed(false), withCredentials(true),
+ preConnect(false)
{
}
@@ -64,6 +65,7 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest
customVerb = other.customVerb;
withCredentials = other.withCredentials;
ssl = other.ssl;
+ preConnect = other.preConnect;
}
QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate()
@@ -74,8 +76,15 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
{
return QHttpNetworkHeaderPrivate::operator==(other)
&& (operation == other.operation)
+ && (priority == other.priority)
+ && (uploadByteDevice == other.uploadByteDevice)
+ && (autoDecompress == other.autoDecompress)
+ && (pipeliningAllowed == other.pipeliningAllowed)
+ // we do not clear the customVerb in setOperation
+ && (operation != QHttpNetworkRequest::Custom || (customVerb == other.customVerb))
+ && (withCredentials == other.withCredentials)
&& (ssl == other.ssl)
- && (uploadByteDevice == other.uploadByteDevice);
+ && (preConnect == other.preConnect);
}
QByteArray QHttpNetworkRequestPrivate::methodName() const
@@ -205,6 +214,15 @@ void QHttpNetworkRequest::setSsl(bool s)
d->ssl = s;
}
+bool QHttpNetworkRequest::isPreConnect() const
+{
+ return d->preConnect;
+}
+void QHttpNetworkRequest::setPreConnect(bool preConnect)
+{
+ d->preConnect = preConnect;
+}
+
qint64 QHttpNetworkRequest::contentLength() const
{
return d->contentLength();
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index fc4a6928c6..ce9fbb1509 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -120,6 +120,9 @@ public:
bool isSsl() const;
void setSsl(bool);
+ bool isPreConnect() const;
+ void setPreConnect(bool preConnect);
+
void setUploadByteDevice(QNonContiguousByteDevice *bd);
QNonContiguousByteDevice* uploadByteDevice() const;
@@ -151,6 +154,7 @@ public:
bool pipeliningAllowed;
bool withCredentials;
bool ssl;
+ bool preConnect;
};
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index a2cee48b22..ee3911c72c 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -107,8 +107,14 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
{
QString result;
QUrl copy = url;
- bool isEncrypted = copy.scheme().toLower() == QLatin1String("https");
+ QString scheme = copy.scheme().toLower();
+ bool isEncrypted = scheme == QLatin1String("https");
copy.setPort(copy.port(isEncrypted ? 443 : 80));
+ if (scheme == QLatin1String("preconnect-http")) {
+ copy.setScheme(QLatin1String("http"));
+ } else if (scheme == QLatin1String("preconnect-https")) {
+ copy.setScheme(QLatin1String("https"));
+ }
result = copy.toString(QUrl::RemoveUserInfo | QUrl::RemovePath |
QUrl::RemoveQuery | QUrl::RemoveFragment | QUrl::FullyEncoded);
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index a895864d76..47cd928541 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -47,6 +47,7 @@
#include "qnetworkreply_p.h"
#include "QtCore/qhash.h"
#include "QtCore/qmutex.h"
+#include "QtCore/qstringlist.h"
#include "QtNetwork/private/qnetworksession_p.h"
#include "qnetworkaccesscachebackend_p.h"
@@ -110,6 +111,22 @@ QNetworkAccessBackend *QNetworkAccessManagerPrivate::findBackend(QNetworkAccessM
return 0;
}
+QStringList QNetworkAccessManagerPrivate::backendSupportedSchemes() const
+{
+ if (QNetworkAccessBackendFactoryData::valid.load()) {
+ QMutexLocker locker(&factoryData()->mutex);
+ QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin();
+ QNetworkAccessBackendFactoryData::ConstIterator end = factoryData()->constEnd();
+ QStringList schemes;
+ while (it != end) {
+ schemes += (*it)->supportedSchemes();
+ ++it;
+ }
+ return schemes;
+ }
+ return QStringList();
+}
+
QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
if (reply->outgoingDataBuffer)
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index bf284414e0..d9657cf750 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -62,6 +62,7 @@ class QAuthenticator;
class QNetworkProxy;
class QNetworkProxyQuery;
class QNetworkRequest;
+class QStringList;
class QUrl;
class QUrlInfo;
class QSslConfiguration;
@@ -219,6 +220,7 @@ class QNetworkAccessBackendFactory
public:
QNetworkAccessBackendFactory();
virtual ~QNetworkAccessBackendFactory();
+ virtual QStringList supportedSchemes() const = 0;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const = 0;
};
diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp
index b6c04dddea..a91751523a 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend.cpp
+++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp
@@ -42,6 +42,7 @@
#include "qnetworkaccessdebugpipebackend_p.h"
#include "QtCore/qdatastream.h"
#include <QCoreApplication>
+#include <QStringList>
#include <QUrlQuery>
#include "private/qnoncontiguousbytedevice_p.h"
@@ -54,6 +55,11 @@ enum {
WriteBufferSize = ReadBufferSize
};
+QStringList QNetworkAccessDebugPipeBackendFactory::supportedSchemes() const
+{
+ return QStringList(QStringLiteral("debugpipe"));
+}
+
QNetworkAccessBackend *
QNetworkAccessDebugPipeBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessdebugpipebackend_p.h b/src/network/access/qnetworkaccessdebugpipebackend_p.h
index 0ae49de132..7593dfa9b7 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend_p.h
+++ b/src/network/access/qnetworkaccessdebugpipebackend_p.h
@@ -102,6 +102,7 @@ private:
class QNetworkAccessDebugPipeBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index 13428cc802..13e7394003 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -49,6 +49,17 @@
QT_BEGIN_NAMESPACE
+QStringList QNetworkAccessFileBackendFactory::supportedSchemes() const
+{
+ QStringList schemes;
+ schemes << QStringLiteral("file")
+ << QStringLiteral("qrc");
+#if defined(Q_OS_ANDROID)
+ schemes << QStringLiteral("assets");
+#endif
+ return schemes;
+}
+
QNetworkAccessBackend *
QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessfilebackend_p.h b/src/network/access/qnetworkaccessfilebackend_p.h
index a52ecef165..157461fee7 100644
--- a/src/network/access/qnetworkaccessfilebackend_p.h
+++ b/src/network/access/qnetworkaccessfilebackend_p.h
@@ -88,6 +88,7 @@ private:
class QNetworkAccessFileBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 737d7d0151..246eb41657 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -43,6 +43,7 @@
#include "qnetworkaccessmanager_p.h"
#include "QtNetwork/qauthenticator.h"
#include "private/qnoncontiguousbytedevice_p.h"
+#include <QStringList>
#ifndef QT_NO_FTP
@@ -61,6 +62,11 @@ static QByteArray makeCacheKey(const QUrl &url)
QUrl::RemoveFragment);
}
+QStringList QNetworkAccessFtpBackendFactory::supportedSchemes() const
+{
+ return QStringList(QStringLiteral("ftp"));
+}
+
QNetworkAccessBackend *
QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessftpbackend_p.h b/src/network/access/qnetworkaccessftpbackend_p.h
index 1bc377d80e..c006d450b8 100644
--- a/src/network/access/qnetworkaccessftpbackend_p.h
+++ b/src/network/access/qnetworkaccessftpbackend_p.h
@@ -111,6 +111,7 @@ private:
class QNetworkAccessFtpBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 10d19bb7aa..91655ef485 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -96,9 +96,11 @@ bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString&
SecProtocolType protocolType = kSecProtocolTypeAny;
if (scheme.compare(QLatin1String("ftp"),Qt::CaseInsensitive)==0) {
protocolType = kSecProtocolTypeFTP;
- } else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0) {
+ } else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0
+ || scheme.compare(QLatin1String("preconnect-http"),Qt::CaseInsensitive)==0) {
protocolType = kSecProtocolTypeHTTP;
- } else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0) {
+ } else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0
+ || scheme.compare(QLatin1String("preconnect-https"),Qt::CaseInsensitive)==0) {
protocolType = kSecProtocolTypeHTTPS;
}
QByteArray proxyHostnameUtf8(proxyHostname.toUtf8());
@@ -431,6 +433,7 @@ static void ensureInitialized()
QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
: QObject(*new QNetworkAccessManagerPrivate, parent)
{
+ Q_D(QNetworkAccessManager);
ensureInitialized();
qRegisterMetaType<QNetworkReply::NetworkError>();
@@ -447,6 +450,19 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
#endif
qRegisterMetaType<QNetworkReply::NetworkError>();
qRegisterMetaType<QSharedPointer<char> >();
+
+#ifndef QT_NO_BEARERMANAGEMENT
+ if (!d->networkSessionRequired) {
+ // if a session is required, we track online state through
+ // the QNetworkSession's signals
+ connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
+ SLOT(_q_onlineStateChanged(bool)));
+ // we would need all active configurations to check for
+ // d->networkConfigurationManager.isOnline(), which is asynchronous
+ // and potentially expensive. We can just check the configuration here
+ d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active);
+ }
+#endif
}
/*!
@@ -833,6 +849,11 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
To restore the default network configuration set the network configuration to the value
returned from QNetworkConfigurationManager::defaultConfiguration().
+ Setting a network configuration means that the QNetworkAccessManager instance will only
+ be using the specified one. In particular, if the default network configuration changes
+ (upon e.g. Wifi being available), this new configuration needs to be enabled
+ manually if desired.
+
\snippet code/src_network_access_qnetworkaccessmanager.cpp 2
If an invalid network configuration is set, a network session will not be created. In this
@@ -844,7 +865,10 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
*/
void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config)
{
- d_func()->createSession(config);
+ Q_D(QNetworkAccessManager);
+ d->networkConfiguration = config;
+ d->customNetworkConfiguration = true;
+ d->createSession(config);
}
/*!
@@ -926,19 +950,73 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
{
Q_D(const QNetworkAccessManager);
- QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
- if (networkSession) {
- // d->online holds online/offline state of this network session.
+ if (d->networkSessionRequired) {
+ QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ if (networkSession) {
+ // d->online holds online/offline state of this network session.
+ if (d->online)
+ return d->networkAccessible;
+ else
+ return NotAccessible;
+ } else {
+ // Network accessibility is either disabled or unknown.
+ return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
+ }
+ } else {
if (d->online)
return d->networkAccessible;
else
return NotAccessible;
- } else {
- // Network accessibility is either disabled or unknown.
- return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
}
}
+#ifndef QT_NO_SSL
+/*!
+ \since 5.2
+
+ Initiates a connection to the host given by \a hostName at port \a port, using
+ \a sslConfiguration. This function is useful to complete the TCP and SSL handshake
+ to a host before the HTTPS request is made, resulting in a lower network latency.
+
+ \note This function has no possibility to report errors.
+
+ \sa connectToHost(), get(), post(), put(), deleteResource()
+*/
+void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port,
+ const QSslConfiguration &sslConfiguration)
+{
+ QUrl url;
+ url.setHost(hostName);
+ url.setPort(port);
+ url.setScheme(QLatin1String("preconnect-https"));
+ QNetworkRequest request(url);
+ if (sslConfiguration != QSslConfiguration::defaultConfiguration())
+ request.setSslConfiguration(sslConfiguration);
+ get(request);
+}
+#endif
+
+/*!
+ \since 5.2
+
+ Initiates a connection to the host given by \a hostName at port \a port.
+ This function is useful to complete the TCP handshake
+ to a host before the HTTP request is made, resulting in a lower network latency.
+
+ \note This function has no possibility to report errors.
+
+ \sa connectToHostEncrypted(), get(), post(), put(), deleteResource()
+*/
+void QNetworkAccessManager::connectToHost(const QString &hostName, quint16 port)
+{
+ QUrl url;
+ url.setHost(hostName);
+ url.setPort(port);
+ url.setScheme(QLatin1String("preconnect-http"));
+ QNetworkRequest request(url);
+ get(request);
+}
+
/*!
\internal
@@ -1050,10 +1128,10 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QDisabledNetworkReply(this, req, op);
}
- if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
+ if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.identifier().isEmpty())) {
QNetworkConfigurationManager manager;
- if (!d->networkConfiguration.isEmpty()) {
- d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
+ if (!d->networkConfiguration.identifier().isEmpty()) {
+ d->createSession(d->networkConfiguration);
} else {
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
d->createSession(manager.defaultConfiguration());
@@ -1083,9 +1161,9 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
#ifndef QT_NO_HTTP
// Since Qt 5 we use the new QNetworkReplyHttpImpl
- if (scheme == QLatin1String("http")
+ if (scheme == QLatin1String("http") || scheme == QLatin1String("preconnect-http")
#ifndef QT_NO_SSL
- || scheme == QLatin1String("https")
+ || scheme == QLatin1String("https") || scheme == QLatin1String("preconnect-https")
#endif
) {
QNetworkReplyHttpImpl *reply = new QNetworkReplyHttpImpl(this, request, op, outgoingData);
@@ -1130,6 +1208,57 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return reply;
}
+/*!
+ \since 5.2
+
+ Lists all the URL schemes supported by the access manager.
+
+ \sa supportedSchemesImplementation()
+*/
+QStringList QNetworkAccessManager::supportedSchemes() const
+{
+ QStringList schemes;
+ QNetworkAccessManager *self = const_cast<QNetworkAccessManager *>(this); // We know we call a const slot
+ QMetaObject::invokeMethod(self, "supportedSchemesImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(QStringList, schemes));
+ schemes.removeDuplicates();
+ return schemes;
+}
+
+/*!
+ \since 5.2
+
+ Lists all the URL schemes supported by the access manager.
+
+ You should not call this function directly; use
+ QNetworkAccessManager::supportedSchemes() instead.
+
+ Reimplement this slot to provide your own supported schemes
+ in a QNetworkAccessManager subclass. It is for instance necessary
+ when your subclass provides support for new protocols.
+
+ Because of binary compatibility constraints, the supportedSchemes()
+ method (introduced in Qt 5.2) is not virtual. Instead, supportedSchemes()
+ will dynamically detect and call this slot.
+
+ \sa supportedSchemes()
+*/
+QStringList QNetworkAccessManager::supportedSchemesImplementation() const
+{
+ Q_D(const QNetworkAccessManager);
+
+ QStringList schemes = d->backendSupportedSchemes();
+ // Those ones don't exist in backends
+#ifndef QT_NO_HTTP
+ schemes << QStringLiteral("http");
+#ifndef QT_NO_SSL
+ if (QSslSocket::supportsSsl())
+ schemes << QStringLiteral("https");
+#endif
+#endif
+ schemes << QStringLiteral("data");
+ return schemes;
+}
/*!
\since 5.0
@@ -1403,7 +1532,7 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
Q_Q(QNetworkAccessManager);
QSharedPointer<QNetworkSession> networkSession(getNetworkSession());
if (networkSession) {
- networkConfiguration = networkSession->configuration().identifier();
+ networkConfiguration = networkSession->configuration();
//disconnect from old session
QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
@@ -1437,6 +1566,18 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
}
}
}
+
+void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
+{
+ // if the user set a config, we only care whether this one is active.
+ // Otherwise, this QNAM is online if there is an online config.
+ if (customNetworkConfiguration) {
+ online = (networkConfiguration.state() & QNetworkConfiguration::Active);
+ } else {
+ online = isOnline;
+ }
+}
+
#endif // QT_NO_BEARERMANAGEMENT
QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 826c8e47d7..67b9bbcb07 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -43,6 +43,9 @@
#define QNETWORKACCESSMANAGER_H
#include <QtCore/QObject>
+#ifndef QT_NO_SSL
+#include <QtNetwork/QSslConfiguration>
+#endif
QT_BEGIN_NAMESPACE
@@ -97,6 +100,9 @@ public:
explicit QNetworkAccessManager(QObject *parent = 0);
~QNetworkAccessManager();
+ // ### Qt 6: turn into virtual
+ QStringList supportedSchemes() const;
+
void clearAccessCache();
#ifndef QT_NO_NETWORKPROXY
@@ -132,6 +138,12 @@ public:
NetworkAccessibility networkAccessible() const;
#endif
+#ifndef QT_NO_SSL
+ void connectToHostEncrypted(const QString &hostName, quint16 port = 443,
+ const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration());
+#endif
+ void connectToHost(const QString &hostName, quint16 port = 80);
+
Q_SIGNALS:
#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
@@ -153,6 +165,9 @@ protected:
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
QIODevice *outgoingData = 0);
+protected Q_SLOTS:
+ QStringList supportedSchemesImplementation() const;
+
private:
friend class QNetworkReplyImplPrivate;
friend class QNetworkReplyHttpImpl;
@@ -165,6 +180,7 @@ private:
#ifndef QT_NO_BEARERMANAGEMENT
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed())
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State))
+ Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool))
#endif
};
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index cf756dad7b..292755e7eb 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -60,6 +60,9 @@
#include "QtNetwork/qnetworkproxy.h"
#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccessauthenticationmanager_p.h"
+#ifndef QT_NO_BEARERMANAGEMENT
+#include "QtNetwork/qnetworkconfigmanager.h"
+#endif
QT_BEGIN_NAMESPACE
@@ -79,6 +82,10 @@ public:
#endif
#ifndef QT_NO_BEARERMANAGEMENT
lastSessionState(QNetworkSession::Invalid),
+ networkConfiguration(networkConfigurationManager.defaultConfiguration()),
+ customNetworkConfiguration(false),
+ networkSessionRequired(networkConfigurationManager.capabilities()
+ & QNetworkConfigurationManager::NetworkSessionRequired),
networkAccessible(QNetworkAccessManager::Accessible),
activeReplyCount(0),
online(false),
@@ -117,6 +124,7 @@ public:
#endif
QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request);
+ QStringList backendSupportedSchemes() const;
#ifndef QT_NO_BEARERMANAGEMENT
void createSession(const QNetworkConfiguration &config);
@@ -127,6 +135,7 @@ public:
void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config,
bool isSeamless);
void _q_networkSessionStateChanged(QNetworkSession::State state);
+ void _q_onlineStateChanged(bool isOnline);
#endif
QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart);
@@ -148,7 +157,12 @@ public:
QSharedPointer<QNetworkSession> networkSessionStrongRef;
QWeakPointer<QNetworkSession> networkSessionWeakRef;
QNetworkSession::State lastSessionState;
- QString networkConfiguration;
+ QNetworkConfigurationManager networkConfigurationManager;
+ QNetworkConfiguration networkConfiguration;
+ // we need to track whether the user set a config or not,
+ // because the default config might change
+ bool customNetworkConfiguration;
+ bool networkSessionRequired;
QNetworkAccessManager::NetworkAccessibility networkAccessible;
int activeReplyCount;
bool online;
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index c7d3846465..ddef970966 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -629,10 +629,15 @@ void QNetworkReplyHttpImplPrivate::postRequest()
QUrl url = request.url();
httpRequest.setUrl(url);
- bool ssl = url.scheme().toLower() == QLatin1String("https");
+ QString scheme = url.scheme().toLower();
+ bool ssl = (scheme == QLatin1String("https")
+ || scheme == QLatin1String("preconnect-https"));
q->setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl);
httpRequest.setSsl(ssl);
+ bool preConnect = (scheme == QLatin1String("preconnect-http")
+ || scheme == QLatin1String("preconnect-https"));
+ httpRequest.setPreConnect(preConnect);
#ifndef QT_NO_NETWORKPROXY
QNetworkProxy transparentProxy, cacheProxy;
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index 615ef21661..40381a04c0 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -41,6 +41,12 @@
#include "qnetworkconfiguration.h"
#include "qnetworkconfiguration_p.h"
+#include <QDebug>
+
+#ifdef Q_OS_BLACKBERRY
+#include "private/qcore_unix_p.h" // qt_safe_open
+#include <sys/pps.h>
+#endif // Q_OS_BLACKBERRY
QT_BEGIN_NAMESPACE
@@ -193,13 +199,95 @@ QT_BEGIN_NAMESPACE
\value BearerEthernet The configuration is for an Ethernet interfaces.
\value BearerWLAN The configuration is for a Wireless LAN interface.
\value Bearer2G The configuration is for a CSD, GPRS, HSCSD, EDGE or cdmaOne interface.
+ \value Bearer3G The configuration is for a 3G interface.
+ \value Bearer4G The configuration is for a 4G interface.
\value BearerCDMA2000 The configuration is for CDMA interface.
\value BearerWCDMA The configuration is for W-CDMA/UMTS interface.
\value BearerHSPA The configuration is for High Speed Packet Access (HSPA) interface.
\value BearerBluetooth The configuration is for a Bluetooth interface.
\value BearerWiMAX The configuration is for a WiMAX interface.
+ \value BearerEVDO The configuration is for an EVDO (3G) interface.
+ \value BearerLTE The configuration is for a LTE (4G) interface.
*/
+#ifdef Q_OS_BLACKBERRY
+static const char cellularStatusFile[] = "/pps/services/radioctrl/modem0/status_public";
+
+#ifdef Q_OS_BLACKBERRY_TABLET
+static bool pps_decoder_is_integer(pps_decoder_t *decoder, const char *name)
+{
+ return (pps_decoder_type(decoder, name) == PPS_TYPE_NUMBER);
+}
+#endif // Q_OS_BLACKBERRY_TABLET
+
+static QNetworkConfiguration::BearerType cellularStatus()
+{
+ QNetworkConfiguration::BearerType ret = QNetworkConfiguration::BearerUnknown;
+
+ int cellularStatusFD;
+ if ((cellularStatusFD = qt_safe_open(cellularStatusFile, O_RDONLY)) == -1) {
+ qWarning() << Q_FUNC_INFO << "failed to open" << cellularStatusFile;
+ return ret;
+ }
+ char buf[2048];
+ if (qt_safe_read(cellularStatusFD, &buf, sizeof(buf)) == -1) {
+ qWarning() << Q_FUNC_INFO << "read from PPS file failed:" << strerror(errno);
+ qt_safe_close(cellularStatusFD);
+ return ret;
+ }
+ pps_decoder_t ppsDecoder;
+ if (pps_decoder_initialize(&ppsDecoder, buf) != PPS_DECODER_OK) {
+ qWarning() << Q_FUNC_INFO << "failed to initialize PPS decoder";
+ qt_safe_close(cellularStatusFD);
+ return ret;
+ }
+ pps_decoder_error_t err;
+ if ((err = pps_decoder_push(&ppsDecoder, 0)) != PPS_DECODER_OK) {
+ qWarning() << Q_FUNC_INFO << "pps_decoder_push failed" << err;
+ pps_decoder_cleanup(&ppsDecoder);
+ qt_safe_close(cellularStatusFD);
+ return ret;
+ }
+ if (!pps_decoder_is_integer(&ppsDecoder, "network_technology")) {
+ qWarning() << Q_FUNC_INFO << "field has not the expected data type";
+ pps_decoder_cleanup(&ppsDecoder);
+ qt_safe_close(cellularStatusFD);
+ return ret;
+ }
+ int type;
+ if (!pps_decoder_get_int(&ppsDecoder, "network_technology", &type)
+ == PPS_DECODER_OK) {
+ qWarning() << Q_FUNC_INFO << "could not read bearer type from PPS";
+ pps_decoder_cleanup(&ppsDecoder);
+ qt_safe_close(cellularStatusFD);
+ return ret;
+ }
+ switch (type) {
+ case 0: // 0 == NONE
+ break; // unhandled
+ case 1: // fallthrough, 1 == GSM
+ case 4: // 4 == CDMA_1X
+ ret = QNetworkConfiguration::Bearer2G;
+ break;
+ case 2: // 2 == UMTS
+ ret = QNetworkConfiguration::BearerWCDMA;
+ break;
+ case 8: // 8 == EVDO
+ ret = QNetworkConfiguration::BearerEVDO;
+ break;
+ case 16: // 16 == LTE
+ ret = QNetworkConfiguration::BearerLTE;
+ break;
+ default:
+ qWarning() << Q_FUNC_INFO << "unhandled bearer type" << type;
+ break;
+ }
+ pps_decoder_cleanup(&ppsDecoder);
+ qt_safe_close(cellularStatusFD);
+ return ret;
+}
+#endif // Q_OS_BLACKBERRY
+
/*!
Constructs an invalid configuration object.
@@ -412,6 +500,8 @@ QList<QNetworkConfiguration> QNetworkConfiguration::children() const
function can be used to retrieve a textural type name for the bearer.
An invalid network configuration always returns the BearerUnknown value.
+
+ \sa bearerTypeName(), bearerTypeFamily()
*/
QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
{
@@ -420,10 +510,74 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
QMutexLocker locker(&d->mutex);
+#ifdef Q_OS_BLACKBERRY
+ // for cellular configurations, we need to determine the exact
+ // type right now, because it might have changed after the last scan
+ if (d->bearerType == QNetworkConfiguration::Bearer2G) {
+ QNetworkConfiguration::BearerType type = cellularStatus();
+ // if reading the status failed for some reason, just
+ // fall back to 2G
+ return (type == QNetworkConfiguration::BearerUnknown)
+ ? QNetworkConfiguration::Bearer2G : type;
+ }
+#endif // Q_OS_BLACKBERRY
+
return d->bearerType;
}
/*!
+ \since 5.2
+
+ Returns the bearer type family used by this network configuration.
+ The following table lists how bearerType() values map to
+ bearerTypeFamily() values:
+
+ \table
+ \header
+ \li bearer type
+ \li bearer type family
+ \row
+ \li BearerUnknown, Bearer2G, BearerEthernet, BearerWLAN,
+ BearerBluetooth
+ \li (same type)
+ \row
+ \li BearerCDMA2000, BearerEVDO, BearerWCDMA, BearerHSPA, Bearer3G
+ \li Bearer3G
+ \row
+ \li BearerWiMAX, BearerLTE, Bearer4G
+ \li Bearer4G
+ \endtable
+
+ An invalid network configuration always returns the BearerUnknown value.
+
+ \sa bearerType(), bearerTypeName()
+*/
+QNetworkConfiguration::BearerType QNetworkConfiguration::bearerTypeFamily() const
+{
+ QNetworkConfiguration::BearerType type = bearerType();
+ switch (type) {
+ case QNetworkConfiguration::BearerUnknown: // fallthrough
+ case QNetworkConfiguration::Bearer2G: // fallthrough
+ case QNetworkConfiguration::BearerEthernet: // fallthrough
+ case QNetworkConfiguration::BearerWLAN: // fallthrough
+ case QNetworkConfiguration::BearerBluetooth:
+ return type;
+ case QNetworkConfiguration::BearerCDMA2000: // fallthrough
+ case QNetworkConfiguration::BearerEVDO: // fallthrough
+ case QNetworkConfiguration::BearerWCDMA: // fallthrough
+ case QNetworkConfiguration::BearerHSPA: // fallthrough
+ case QNetworkConfiguration::Bearer3G:
+ return QNetworkConfiguration::Bearer3G;
+ case QNetworkConfiguration::BearerWiMAX: // fallthrough
+ case QNetworkConfiguration::BearerLTE: // fallthrough
+ case QNetworkConfiguration::Bearer4G:
+ return QNetworkConfiguration::Bearer4G;
+ default:
+ qWarning() << "unknown bearer type" << type;
+ return QNetworkConfiguration::BearerUnknown;
+ }
+}
+/*!
Returns the type of bearer used by this network configuration as a string.
The string is not translated and therefore can not be shown to the user. The subsequent table
@@ -450,6 +604,12 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
\li Bearer2G
\li 2G
\row
+ \li Bearer3G
+ \li 3G
+ \row
+ \li Bearer4G
+ \li 4G
+ \row
\li BearerCDMA2000
\li CDMA2000
\row
@@ -464,13 +624,19 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
\row
\li BearerWiMAX
\li WiMAX
+ \row
+ \li BearerEVDO
+ \li EVDO
+ \row
+ \li BearerLTE
+ \li LTE
\endtable
This function returns an empty string if this is an invalid configuration, a network
configuration of type \l QNetworkConfiguration::ServiceNetwork or
\l QNetworkConfiguration::UserChoice.
- \sa bearerType()
+ \sa bearerType(), bearerTypeFamily()
*/
QString QNetworkConfiguration::bearerTypeName() const
{
@@ -489,7 +655,25 @@ QString QNetworkConfiguration::bearerTypeName() const
case BearerWLAN:
return QStringLiteral("WLAN");
case Bearer2G:
+#ifdef Q_OS_BLACKBERRY
+ {
+ // for cellular configurations, we need to determine the exact
+ // type right now, because it might have changed after the last scan
+ QNetworkConfiguration::BearerType type = cellularStatus();
+ if (type == QNetworkConfiguration::BearerWCDMA) {
+ return QStringLiteral("WCDMA");
+ } else if (type == QNetworkConfiguration::BearerEVDO) {
+ return QStringLiteral("EVDO");
+ }else if (type == QNetworkConfiguration::BearerLTE) {
+ return QStringLiteral("LTE");
+ }
+ }
+#endif // Q_OS_BLACKBERRY
return QStringLiteral("2G");
+ case Bearer3G:
+ return QStringLiteral("3G");
+ case Bearer4G:
+ return QStringLiteral("4G");
case BearerCDMA2000:
return QStringLiteral("CDMA2000");
case BearerWCDMA:
@@ -500,6 +684,10 @@ QString QNetworkConfiguration::bearerTypeName() const
return QStringLiteral("Bluetooth");
case BearerWiMAX:
return QStringLiteral("WiMAX");
+ case BearerEVDO:
+ return QStringLiteral("EVDO");
+ case BearerLTE:
+ return QStringLiteral("LTE");
case BearerUnknown:
break;
}
diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h
index 25dafcb282..8887525a2f 100644
--- a/src/network/bearer/qnetworkconfiguration.h
+++ b/src/network/bearer/qnetworkconfiguration.h
@@ -97,7 +97,11 @@ public:
BearerWCDMA,
BearerHSPA,
BearerBluetooth,
- BearerWiMAX
+ BearerWiMAX,
+ BearerEVDO,
+ BearerLTE,
+ Bearer3G,
+ Bearer4G
};
StateFlags state() const;
@@ -105,6 +109,7 @@ public:
Purpose purpose() const;
BearerType bearerType() const;
+ BearerType bearerTypeFamily() const;
QString bearerTypeName() const;
QString identifier() const;
diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf
index 048b3325b6..f4779ae8fe 100644
--- a/src/network/doc/qtnetwork.qdocconf
+++ b/src/network/doc/qtnetwork.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/network \
imagedirs += images \
../../../examples/network/doc/images
+
+navigation.landingpage = "Qt Network"
+navigation.cppclassespage = "Qt Network C++ Classes"
diff --git a/src/network/doc/src/qtnetwork.qdoc b/src/network/doc/src/qtnetwork.qdoc
index 6d9f6023ab..2faafff82e 100644
--- a/src/network/doc/src/qtnetwork.qdoc
+++ b/src/network/doc/src/qtnetwork.qdoc
@@ -65,6 +65,7 @@
\module QtNetwork
\title Qt Network C++ Classes
\ingroup modules
+ \qtvariable network
\brief Provides classes to make network programming easier and portable
To include the definitions of the module's classes, use the
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index dc67b0d835..5ef428305c 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -189,7 +189,7 @@ static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr,
} else {
scopeId->clear();
}
- return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd());
+ return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd()) == 0;
}
bool QHostAddressPrivate::parse()
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index f2a1633bd3..2e920ad69f 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -545,7 +545,25 @@ void QHttpSocketEngine::slotSocketReadNotification()
return;
}
- readResponseContent:
+ if (d->state == ConnectSent) {
+ d->reply->d_func()->state = QHttpNetworkReplyPrivate::NothingDoneState;
+ d->state = ReadResponseHeader;
+ }
+
+ if (d->state == ReadResponseHeader) {
+ bool ok = readHttpHeader();
+ if (!ok) {
+ // protocol error, this isn't HTTP
+ d->socket->close();
+ setState(QAbstractSocket::UnconnectedState);
+ setError(QAbstractSocket::ProxyProtocolError, tr("Did not receive HTTP response from proxy"));
+ emitConnectionNotification();
+ return;
+ }
+ if (d->state == ReadResponseHeader)
+ return; // readHttpHeader() was not done yet, need to wait for more header data
+ }
+
if (d->state == ReadResponseContent) {
char dummybuffer[4096];
while (d->pendingResponseData) {
@@ -564,31 +582,8 @@ void QHttpSocketEngine::slotSocketReadNotification()
}
if (d->pendingResponseData > 0)
return;
- d->state = SendAuthentication;
- slotSocketConnected();
- return;
- }
-
- bool ok = true;
- if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::NothingDoneState)
- d->reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
- if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState) {
- ok = d->reply->d_func()->readStatus(d->socket) != -1;
- if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState)
- return; //Not done parsing headers yet, wait for more data
- }
- if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState) {
- ok = d->reply->d_func()->readHeader(d->socket) != -1;
- if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState)
- return; //Not done parsing headers yet, wait for more data
- }
- if (!ok) {
- // protocol error, this isn't HTTP
- d->socket->close();
- setState(QAbstractSocket::UnconnectedState);
- setError(QAbstractSocket::ProxyProtocolError, tr("Did not receive HTTP response from proxy"));
- emitConnectionNotification();
- return;
+ if (d->reply->d_func()->statusCode == 407)
+ d->state = SendAuthentication;
}
int statusCode = d->reply->statusCode();
@@ -664,16 +659,8 @@ void QHttpSocketEngine::slotSocketReadNotification()
if (willClose) {
d->socket->connectToHost(d->proxy.hostName(), d->proxy.port());
} else {
- bool ok;
- int contentLength = d->reply->headerField("Content-Length").toInt(&ok);
- if (ok && contentLength > 0) {
- d->state = ReadResponseContent;
- d->pendingResponseData = contentLength;
- goto readResponseContent;
- } else {
- d->state = SendAuthentication;
- slotSocketConnected();
- }
+ // send the HTTP CONNECT again
+ slotSocketConnected();
}
return;
}
@@ -701,6 +688,39 @@ void QHttpSocketEngine::slotSocketReadNotification()
emitConnectionNotification();
}
+bool QHttpSocketEngine::readHttpHeader()
+{
+ Q_D(QHttpSocketEngine);
+
+ if (d->state != ReadResponseHeader)
+ return false;
+
+ bool ok = true;
+ if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::NothingDoneState) {
+ // do not keep old content sizes, status etc. around
+ d->reply->d_func()->clearHttpLayerInformation();
+ d->reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
+ }
+ if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState) {
+ ok = d->reply->d_func()->readStatus(d->socket) != -1;
+ if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState)
+ return true; //Not done parsing headers yet, wait for more data
+ }
+ if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState) {
+ ok = d->reply->d_func()->readHeader(d->socket) != -1;
+ if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState)
+ return true; //Not done parsing headers yet, wait for more data
+ }
+ if (ok) {
+ bool contentLengthOk;
+ int contentLength = d->reply->headerField("Content-Length").toInt(&contentLengthOk);
+ if (contentLengthOk && contentLength > 0)
+ d->pendingResponseData = contentLength;
+ d->state = ReadResponseContent; // we are done reading the header
+ }
+ return ok;
+}
+
void QHttpSocketEngine::slotSocketBytesWritten()
{
Q_D(QHttpSocketEngine);
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index bac6d9edf7..7567772517 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -75,7 +75,8 @@ public:
ConnectSent,
Connected,
SendAuthentication,
- ReadResponseContent
+ ReadResponseContent,
+ ReadResponseHeader
};
QHttpSocketEngine(QObject *parent = 0);
~QHttpSocketEngine();
@@ -156,6 +157,8 @@ private:
void emitWriteNotification();
void emitConnectionNotification();
+ bool readHttpHeader();
+
Q_DECLARE_PRIVATE(QHttpSocketEngine)
Q_DISABLE_COPY(QHttpSocketEngine)
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index 4e33001d8d..ec771e1f49 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -161,12 +161,20 @@ QT_BEGIN_NAMESPACE
mechanism for renegotiating the connection parameters. When enabled, this
option can allow connections for legacy servers, but it introduces the
possibility that an attacker could inject plaintext into the SSL session.
+ \value SslOptionDisableSessionSharing Disables SSL session sharing via
+ the session ID handshake attribute.
+ \value SslOptionDisableSessionPersistence Disables storing the SSL session
+ in ASN.1 format as returned by QSslConfiguration::session(). Enabling
+ this feature adds memory overhead of approximately 1K per used session
+ ticket.
By default, SslOptionDisableEmptyFragments is turned on since this causes
problems with a large number of servers. SslOptionDisableLegacyRenegotiation
is also turned on, since it introduces a security risk.
SslOptionDisableCompression is turned on to prevent the attack publicised by
- CRIME. The other options are turned off.
+ CRIME.
+ SslOptionDisableSessionPersistence is turned on to optimize memory usage.
+ The other options are turned off.
Note: Availability of above options depends on the version of the SSL
backend in use.
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index 06d80965e2..21d03cb703 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -95,7 +95,9 @@ namespace QSsl {
SslOptionDisableSessionTickets = 0x02,
SslOptionDisableCompression = 0x04,
SslOptionDisableServerNameIndication = 0x08,
- SslOptionDisableLegacyRenegotiation = 0x10
+ SslOptionDisableLegacyRenegotiation = 0x10,
+ SslOptionDisableSessionSharing = 0x20,
+ SslOptionDisableSessionPersistence = 0x40
};
Q_DECLARE_FLAGS(SslOptions, SslOption)
}
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index afbd4fac77..6cc06dfbd2 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -49,7 +49,8 @@ QT_BEGIN_NAMESPACE
const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOptionDisableEmptyFragments
|QSsl::SslOptionDisableLegacyRenegotiation
- |QSsl::SslOptionDisableCompression;
+ |QSsl::SslOptionDisableCompression
+ |QSsl::SslOptionDisableSessionPersistence;
/*!
\class QSslConfiguration
@@ -182,7 +183,9 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->peerVerifyMode == other.d->peerVerifyMode &&
d->peerVerifyDepth == other.d->peerVerifyDepth &&
d->allowRootCertOnDemandLoading == other.d->allowRootCertOnDemandLoading &&
- d->sslOptions == other.d->sslOptions;
+ d->sslOptions == other.d->sslOptions &&
+ d->sslSession == other.d->sslSession &&
+ d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint;
}
/*!
@@ -216,7 +219,9 @@ bool QSslConfiguration::isNull() const
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
d->peerCertificateChain.count() == 0 &&
- d->sslOptions == QSslConfigurationPrivate::defaultSslOptions);
+ d->sslOptions == QSslConfigurationPrivate::defaultSslOptions &&
+ d->sslSession.isNull() &&
+ d->sslSessionTicketLifeTimeHint == -1);
}
/*!
@@ -594,6 +599,60 @@ bool QSslConfiguration::testSslOption(QSsl::SslOption option) const
}
/*!
+ \since 5.2
+
+ If QSsl::SslOptionDisableSessionPersistence was turned off, this
+ function returns the session used in the SSL handshake in ASN.1
+ format, suitable to e.g. be persisted to disk. If no session was
+ used or QSsl::SslOptionDisableSessionPersistence was not turned off,
+ this function returns an empty QByteArray.
+
+ \b{Note:} When persisting the session to disk or similar, be
+ careful not to expose the session to a potential attacker, as
+ knowledge of the session allows for eavesdropping on data
+ encrypted with the session parameters.
+
+ \sa setSession(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ */
+QByteArray QSslConfiguration::session() const
+{
+ return d->sslSession;
+}
+
+/*!
+ \since 5.2
+
+ Sets the session to be used in an SSL handshake.
+ QSsl::SslOptionDisableSessionPersistence must be turned off
+ for this to work, and \a session must be in ASN.1 format
+ as returned by session().
+
+ \sa session(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ */
+void QSslConfiguration::setSession(const QByteArray &session)
+{
+ d->sslSession = session;
+}
+
+/*!
+ \since 5.2
+
+ If QSsl::SslOptionDisableSessionPersistence was turned off, this
+ function returns the session ticket life time hint sent by the
+ server (which might be 0).
+ If the server did not send a session ticket (e.g. when
+ resuming a session or when the server does not support it) or
+ QSsl::SslOptionDisableSessionPersistence was not turned off,
+ this function returns -1.
+
+ \sa session(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ */
+int QSslConfiguration::sessionTicketLifeTimeHint() const
+{
+ return d->sslSessionTicketLifeTimeHint;
+}
+
+/*!
Returns the default SSL configuration to be used in new SSL
connections.
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 0000382ed5..949ce70d4c 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -124,6 +124,10 @@ public:
void setSslOption(QSsl::SslOption option, bool on);
bool testSslOption(QSsl::SslOption option) const;
+ QByteArray session() const;
+ void setSession(const QByteArray &session);
+ int sessionTicketLifeTimeHint() const;
+
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 54b7264d3d..71ee8d2bfe 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -85,7 +85,8 @@ public:
peerVerifyDepth(0),
allowRootCertOnDemandLoading(true),
peerSessionShared(false),
- sslOptions(QSslConfigurationPrivate::defaultSslOptions)
+ sslOptions(QSslConfigurationPrivate::defaultSslOptions),
+ sslSessionTicketLifeTimeHint(-1)
{ }
QSslCertificate peerCertificate;
@@ -110,6 +111,9 @@ public:
Q_AUTOTEST_EXPORT static const QSsl::SslOptions defaultSslOptions;
+ QByteArray sslSession;
+ int sslSessionTicketLifeTimeHint;
+
// in qsslsocket.cpp:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index 22ad42116b..6d281c390d 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -57,7 +57,8 @@ extern QString getErrorsFromOpenSsl();
QSslContext::QSslContext()
: ctx(0),
pkey(0),
- session(0)
+ session(0),
+ m_sessionTicketLifeTimeHint(-1)
{
}
@@ -258,6 +259,10 @@ init_context:
if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
+ // set persisted session if the user set it
+ if (!configuration.session().isEmpty())
+ sslContext->setSessionASN1(configuration.session());
+
return sslContext;
}
@@ -267,6 +272,12 @@ SSL* QSslContext::createSsl()
SSL* ssl = q_SSL_new(ctx);
q_SSL_clear(ssl);
+ if (!session && !sessionASN1().isEmpty()
+ && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
+ const unsigned char *data = reinterpret_cast<const unsigned char *>(m_sessionASN1.constData());
+ session = q_d2i_SSL_SESSION(0, &data, m_sessionASN1.size()); // refcount is 1 already, set by function above
+ }
+
if (session) {
// Try to resume the last session we cached
if (!q_SSL_set_session(ssl, session)) {
@@ -292,8 +303,34 @@ bool QSslContext::cacheSession(SSL* ssl)
// cache the session the caller gave us and increase reference count
session = q_SSL_get1_session(ssl);
- return (session != NULL);
+ if (session && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
+ int sessionSize = q_i2d_SSL_SESSION(session, 0);
+ if (sessionSize > 0) {
+ m_sessionASN1.resize(sessionSize);
+ unsigned char *data = reinterpret_cast<unsigned char *>(m_sessionASN1.data());
+ if (!q_i2d_SSL_SESSION(session, &data))
+ qWarning("could not store persistent version of SSL session");
+ m_sessionTicketLifeTimeHint = session->tlsext_tick_lifetime_hint;
+ }
+ }
+
+ return (session != 0);
+}
+
+QByteArray QSslContext::sessionASN1() const
+{
+ return m_sessionASN1;
+}
+
+void QSslContext::setSessionASN1(const QByteArray &session)
+{
+ m_sessionASN1 = session;
+}
+
+int QSslContext::sessionTicketLifeTimeHint() const
+{
+ return m_sessionTicketLifeTimeHint;
}
QSslError::SslError QSslContext::error() const
diff --git a/src/network/ssl/qsslcontext_p.h b/src/network/ssl/qsslcontext_p.h
index c8578d349e..2b596798a6 100644
--- a/src/network/ssl/qsslcontext_p.h
+++ b/src/network/ssl/qsslcontext_p.h
@@ -69,6 +69,9 @@ public:
SSL* createSsl();
bool cacheSession(SSL*); // should be called when handshake completed
+ QByteArray sessionASN1() const;
+ void setSessionASN1(const QByteArray &sessionASN1);
+ int sessionTicketLifeTimeHint() const;
protected:
QSslContext();
@@ -76,6 +79,8 @@ private:
SSL_CTX* ctx;
EVP_PKEY *pkey;
SSL_SESSION *session;
+ QByteArray m_sessionASN1;
+ int m_sessionTicketLifeTimeHint;
QSslError::SslError errorCode;
QString errorStr;
QSslConfiguration sslConfiguration;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index f2310356df..0e7ac39d14 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -903,6 +903,8 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.peerVerifyMode = configuration.peerVerifyMode();
d->configuration.protocol = configuration.protocol();
d->configuration.sslOptions = configuration.d->sslOptions;
+ d->configuration.sslSession = configuration.session();
+ d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
// if the CA certificates were set explicitly (either via
// QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(),
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 30103edc29..e94df10fed 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE
#if defined(Q_OS_MACX)
#define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file
- PtrSecCertificateGetData QSslSocketPrivate::ptrSecCertificateGetData = 0;
+ PtrSecCertificateCopyData QSslSocketPrivate::ptrSecCertificateCopyData = 0;
PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0;
PtrSecTrustCopyAnchorCertificates QSslSocketPrivate::ptrSecTrustCopyAnchorCertificates = 0;
#elif defined(Q_OS_WIN)
@@ -492,8 +492,8 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
#if defined(Q_OS_MACX)
QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security");
if (securityLib.load()) {
- ptrSecCertificateGetData = (PtrSecCertificateGetData) securityLib.resolve("SecCertificateGetData");
- if (!ptrSecCertificateGetData)
+ ptrSecCertificateCopyData = (PtrSecCertificateCopyData) securityLib.resolve("SecCertificateCopyData");
+ if (!ptrSecCertificateCopyData)
qWarning("could not resolve symbols in security library"); // should never happen
ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates");
@@ -629,12 +629,11 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
CFArrayRef cfCerts;
OSStatus status = 1;
- OSStatus SecCertificateGetData (
- SecCertificateRef certificate,
- CSSM_DATA_PTR data
+ CFDataRef SecCertificateCopyData (
+ SecCertificateRef certificate
);
- if (ptrSecCertificateGetData) {
+ if (ptrSecCertificateCopyData) {
if (ptrSecTrustSettingsCopyCertificates)
status = ptrSecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
else if (ptrSecTrustCopyAnchorCertificates)
@@ -643,15 +642,16 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
CFIndex size = CFArrayGetCount(cfCerts);
for (CFIndex i = 0; i < size; ++i) {
SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
- CSSM_DATA data;
- CSSM_DATA_PTR dataPtr = &data;
- if (ptrSecCertificateGetData(cfCert, dataPtr)) {
+ CFDataRef data;
+
+ data = ptrSecCertificateCopyData(cfCert);
+
+ if (data == NULL) {
qWarning("error retrieving a CA certificate from the system store");
} else {
- int len = data.Length;
- char *rawData = reinterpret_cast<char *>(data.Data);
- QByteArray rawCert(rawData, len);
+ QByteArray rawCert = QByteArray::fromRawData((const char *)CFDataGetBytePtr(data), CFDataGetLength(data));
systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der));
+ CFRelease(data);
}
}
CFRelease(cfCerts);
@@ -1458,9 +1458,17 @@ void QSslSocketBackendPrivate::continueHandshake()
#endif
// Cache this SSL session inside the QSslContext
- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionTickets)) {
- if (!sslContextPointer->cacheSession(ssl))
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
+ if (!sslContextPointer->cacheSession(ssl)) {
sslContextPointer.clear(); // we could not cache the session
+ } else {
+ // Cache the session for permanent usage as well
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
+ if (!sslContextPointer->sessionASN1().isEmpty())
+ configuration.sslSession = sslContextPointer->sessionASN1();
+ configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
+ }
+ }
}
connectionEncrypted = true;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index d2a349455e..a010075436 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -332,6 +332,8 @@ DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYA
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
+DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
+DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return)
#define RESOLVEFUNC(func) \
if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
@@ -548,7 +550,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
#ifdef Q_OS_OPENBSD
libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint);
#endif
-#ifdef SHLIB_VERSION_NUMBER
+#if defined(SHLIB_VERSION_NUMBER) && !defined(Q_OS_QNX) // on QNX, the libs are always libssl.so and libcrypto.so
// first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER>
libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER));
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
@@ -801,6 +803,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_load_verify_locations)
RESOLVEFUNC(SSLeay)
RESOLVEFUNC(SSLeay_version)
+ RESOLVEFUNC(i2d_SSL_SESSION)
+ RESOLVEFUNC(d2i_SSL_SESSION)
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 2e01ee4d31..1fd98cc7fb 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -469,6 +469,8 @@ void q_OPENSSL_add_all_algorithms_conf();
int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);
long q_SSLeay();
const char *q_SSLeay_version(int type);
+int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
+SSL_SESSION *q_d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
// Helper function
class QDateTime;
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 6ce34ba06f..6281753225 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -79,7 +79,7 @@
QT_BEGIN_NAMESPACE
#if defined(Q_OS_MACX)
- typedef OSStatus (*PtrSecCertificateGetData)(SecCertificateRef, CSSM_DATA_PTR);
+ typedef CFDataRef (*PtrSecCertificateCopyData)(SecCertificateRef);
typedef OSStatus (*PtrSecTrustSettingsCopyCertificates)(int, CFArrayRef*);
typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*);
#endif
@@ -146,7 +146,7 @@ public:
static void addDefaultCaCertificates(const QList<QSslCertificate> &certs);
#if defined(Q_OS_MACX)
- static PtrSecCertificateGetData ptrSecCertificateGetData;
+ static PtrSecCertificateCopyData ptrSecCertificateCopyData;
static PtrSecTrustSettingsCopyCertificates ptrSecTrustSettingsCopyCertificates;
static PtrSecTrustCopyAnchorCertificates ptrSecTrustCopyAnchorCertificates;
#elif defined(Q_OS_WIN)
diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf
index e76a23844b..5b6d09dfcd 100644
--- a/src/opengl/doc/qtopengl.qdocconf
+++ b/src/opengl/doc/qtopengl.qdocconf
@@ -19,7 +19,7 @@ exampledirs += ../../../examples/opengl \
imagedirs += images \
../../../examples/opengl/doc/images
-depends += qtcore qtgui qtwidgets
+depends += qtdoc qtcore qtgui qtwidgets
examplesinstallpath = opengl
@@ -50,3 +50,6 @@ qhp.QtOpenGL.subprojects.classes.title = C++ Classes
qhp.QtOpenGL.subprojects.classes.indexTitle = Qt OpenGL C++ Classes
qhp.QtOpenGL.subprojects.classes.selectors = class fake:headerfile
qhp.QtOpenGL.subprojects.classes.sortPages = true
+
+navigation.landingpage = "Qt OpenGL"
+navigation.cppclassespage = "Qt OpenGL C++ Classes"
diff --git a/src/opengl/doc/src/qtopengl-module.qdoc b/src/opengl/doc/src/qtopengl-module.qdoc
index 901766ae46..8619f04a97 100644
--- a/src/opengl/doc/src/qtopengl-module.qdoc
+++ b/src/opengl/doc/src/qtopengl-module.qdoc
@@ -29,6 +29,7 @@
\module QtOpenGL
\title Qt OpenGL C++ Classes
\ingroup modules
+ \qtvariable opengl
\brief The Qt OpenGL module offers classes that make it easy to
use OpenGL in Qt applications.
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
index c78c57b86f..d9bd9a78e4 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
@@ -72,7 +72,8 @@ public:
Device_Touchscreen = 0x04,
Device_Keyboard = 0x08,
Device_DRM = 0x10,
- Device_Tablet = 0x20,
+ Device_DRM_PrimaryGPU = 0x20,
+ Device_Tablet = 0x40,
Device_InputMask = Device_Mouse | Device_Touchpad | Device_Touchscreen | Device_Keyboard | Device_Tablet,
Device_VideoMask = Device_DRM
};
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
index 9e0ce47e18..ac902b4140 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
@@ -149,8 +149,16 @@ QStringList QDeviceDiscovery::scanConnectedDevices()
QString candidate = QString::fromUtf8(udev_device_get_devnode(udevice));
if ((m_types & Device_InputMask) && candidate.startsWith(QLatin1String(QT_EVDEV_DEVICE)))
devices << candidate;
- if ((m_types & Device_VideoMask) && candidate.startsWith(QLatin1String(QT_DRM_DEVICE)))
- devices << candidate;
+ if ((m_types & Device_VideoMask) && candidate.startsWith(QLatin1String(QT_DRM_DEVICE))) {
+ if (m_types & Device_DRM_PrimaryGPU) {
+ udev_device *pci = udev_device_get_parent_with_subsystem_devtype(udevice, "pci", 0);
+ if (pci) {
+ if (qstrcmp(udev_device_get_sysattr_value(pci, "boot_vga"), "1") == 0)
+ devices << candidate;
+ }
+ } else
+ devices << candidate;
+ }
udev_device_unref(udevice);
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 8152f74067..34ba21afdc 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -106,6 +106,14 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
+ // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation
+ if (eglGetCurrentContext() == m_eglContext &&
+ eglGetCurrentDisplay() == m_eglDisplay &&
+ eglGetCurrentSurface(EGL_READ) == eglSurface &&
+ eglGetCurrentSurface(EGL_DRAW) == eglSurface) {
+ return true;
+ }
+
bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
if (!ok)
qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
index 58f24c0a04..80453816fc 100644
--- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
+++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
@@ -41,17 +41,6 @@
#include "qxlibeglintegration_p.h"
-static int countBits(unsigned long mask)
-{
- int count = 0;
- while (mask != 0) {
- if (mask & 1)
- ++count;
- mask >>= 1;
- }
- return count;
-}
-
VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
{
VisualID visualId = 0;
@@ -92,9 +81,9 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
return visualId;
}
- int visualRedSize = countBits(chosenVisualInfo->red_mask);
- int visualGreenSize = countBits(chosenVisualInfo->green_mask);
- int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
+ int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask);
+ int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask);
+ int visualBlueSize = qPopulationCount(chosenVisualInfo->blue_mask);
int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
bool visualMatchesConfig = false;
diff --git a/src/platformsupport/eventdispatchers/eventdispatchers.pri b/src/platformsupport/eventdispatchers/eventdispatchers.pri
index 6e16a46b34..c9bbe1f5b7 100644
--- a/src/platformsupport/eventdispatchers/eventdispatchers.pri
+++ b/src/platformsupport/eventdispatchers/eventdispatchers.pri
@@ -8,6 +8,14 @@ HEADERS +=\
$$PWD/qgenericunixeventdispatcher_p.h\
}
+ios {
+OBJECTIVE_SOURCES +=\
+ $$PWD/qeventdispatcher_cf.mm
+
+HEADERS +=\
+ $$PWD/qeventdispatcher_cf_p.h
+}
+
contains(QT_CONFIG, glib) {
SOURCES +=$$PWD/qeventdispatcher_glib.cpp
HEADERS +=$$PWD/qeventdispatcher_glib_p.h
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
index e9bf039047..78f97d5556 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
@@ -39,52 +39,35 @@
**
****************************************************************************/
-#include "qioseventdispatcher.h"
-#import "qiosapplicationdelegate.h"
+#include "qeventdispatcher_cf_p.h"
#include <qdebug.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QThread>
#include <QtCore/private/qcoreapplication_p.h>
+
+#include <limits>
+
#include <UIKit/UIApplication.h>
QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE
-static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2)
-{
- return info1 == info2;
-}
+static const CFTimeInterval kCFTimeIntervalMinimum = 0;
+static const CFTimeInterval kCFTimeIntervalDistantFuture = std::numeric_limits<CFTimeInterval>::max();
-void QIOSEventDispatcher::postedEventsRunLoopCallback(void *info)
-{
- QIOSEventDispatcher *self = static_cast<QIOSEventDispatcher *>(info);
- self->processPostedEvents();
-}
-
-void QIOSEventDispatcher::nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info)
+void QEventDispatcherCoreFoundation::nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info)
{
// The (one and only) CFRunLoopTimer has fired, which means that at least
// one QTimer should now fire as well. Note that CFRunLoopTimer's callback will
// never recurse. So if the app starts a new QEventLoop within this callback, other
// timers will stop working. The work-around is to forward the callback to a
// dedicated CFRunLoopSource that can recurse:
- QIOSEventDispatcher *self = static_cast<QIOSEventDispatcher *>(info);
- CFRunLoopSourceSignal(self->m_blockingTimerRunLoopSource);
-}
-
-void QIOSEventDispatcher::blockingTimerRunLoopCallback(void *info)
-{
- // TODO:
- // We also need to block this new timer source
- // along with the posted event source when calling processEvents()
- // "manually" to prevent livelock deep in CFRunLoop.
-
- QIOSEventDispatcher *self = static_cast<QIOSEventDispatcher *>(info);
- self->m_timerInfoList.activateTimers();
- self->maybeStartCFRunLoopTimer();
+ QEventDispatcherCoreFoundation *self = static_cast<QEventDispatcherCoreFoundation *>(info);
+ self->m_blockingTimerRunLoopSource.signal();
+ // FIXME: And not wake up main run loop?
}
-void QIOSEventDispatcher::maybeStartCFRunLoopTimer()
+void QEventDispatcherCoreFoundation::maybeStartCFRunLoopTimer()
{
// Find out when the next registered timer should fire, and schedule
// runLoopTimer accordingly. If the runLoopTimer does not yet exist, and
@@ -99,7 +82,6 @@ void QIOSEventDispatcher::maybeStartCFRunLoopTimer()
if (m_runLoopTimerRef == 0) {
// start the CFRunLoopTimer
- CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.);
// calculate when the next timer should fire:
struct timespec tv;
@@ -108,17 +90,19 @@ void QIOSEventDispatcher::maybeStartCFRunLoopTimer()
} else {
// this shouldn't really happen, but in case it does, set the timer
// to fire a some point in the distant future:
- interval = oneyear;
+ interval = kCFTimeIntervalDistantFuture;
}
ttf += interval;
CFRunLoopTimerContext info = { 0, this, 0, 0, 0 };
// create the timer with a large interval, as recommended by the CFRunLoopTimerSetNextFireDate()
// documentation, since we will adjust the timer's time-to-fire as needed to keep Qt timers working
- m_runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QIOSEventDispatcher::nonBlockingTimerRunLoopCallback, &info);
+ m_runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, kCFTimeIntervalDistantFuture, 0, 0, QEventDispatcherCoreFoundation::nonBlockingTimerRunLoopCallback, &info);
Q_ASSERT(m_runLoopTimerRef != 0);
- CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimerRef, kCFRunLoopCommonModes);
+ CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
+ CFRunLoopAddTimer(mainRunLoop, m_runLoopTimerRef, kCFRunLoopCommonModes);
+ CFRunLoopAddTimer(mainRunLoop, m_runLoopTimerRef, (CFStringRef) UITrackingRunLoopMode);
} else {
struct timespec tv;
// Calculate when the next timer should fire:
@@ -135,7 +119,7 @@ void QIOSEventDispatcher::maybeStartCFRunLoopTimer()
}
}
-void QIOSEventDispatcher::maybeStopCFRunLoopTimer()
+void QEventDispatcherCoreFoundation::maybeStopCFRunLoopTimer()
{
if (m_runLoopTimerRef == 0)
return;
@@ -145,96 +129,142 @@ void QIOSEventDispatcher::maybeStopCFRunLoopTimer()
m_runLoopTimerRef = 0;
}
-void QIOSEventDispatcher::processPostedEvents()
-{
- QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents);
-}
-
-QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
+QEventDispatcherCoreFoundation::QEventDispatcherCoreFoundation(QObject *parent)
: QAbstractEventDispatcher(parent)
, m_interrupted(false)
+ , m_postedEventsRunLoopSource(this, &QEventDispatcherCoreFoundation::processPostedEvents)
+ , m_blockingTimerRunLoopSource(this, &QEventDispatcherCoreFoundation::processTimers)
+ , m_awakeAndBlockObserver(this, &QEventDispatcherCoreFoundation::handleRunLoopActivity,
+ kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting)
, m_runLoopTimerRef(0)
{
m_cfSocketNotifier.setHostEventDispatcher(this);
- CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
- CFRunLoopSourceContext context;
- bzero(&context, sizeof(CFRunLoopSourceContext));
- context.equal = runLoopSourceEqualCallback;
- context.info = this;
-
- // source used to handle timers:
- context.perform = QIOSEventDispatcher::blockingTimerRunLoopCallback;
- m_blockingTimerRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
- Q_ASSERT(m_blockingTimerRunLoopSource);
- CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
-
- // source used to handle posted events:
- context.perform = QIOSEventDispatcher::postedEventsRunLoopCallback;
- m_postedEventsRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
- Q_ASSERT(m_postedEventsRunLoopSource);
- CFRunLoopAddSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes);
+ m_postedEventsRunLoopSource.addToMode(kCFRunLoopCommonModes);
+
+ m_blockingTimerRunLoopSource.addToMode(kCFRunLoopCommonModes);
+ m_blockingTimerRunLoopSource.addToMode(CFStringRef(UITrackingRunLoopMode));
+
+ m_awakeAndBlockObserver.addToMode(kCFRunLoopCommonModes);
}
-QIOSEventDispatcher::~QIOSEventDispatcher()
+QEventDispatcherCoreFoundation::~QEventDispatcherCoreFoundation()
{
- CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
- CFRunLoopRemoveSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes);
- CFRelease(m_postedEventsRunLoopSource);
-
qDeleteAll(m_timerInfoList);
maybeStopCFRunLoopTimer();
- CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
- CFRelease(m_blockingTimerRunLoopSource);
m_cfSocketNotifier.removeSocketNotifiers();
}
-bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+void QEventDispatcherCoreFoundation::processPostedEvents()
+{
+ QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents);
+}
+
+void QEventDispatcherCoreFoundation::processTimers()
+{
+ // TODO:
+ // We also need to block this new timer source
+ // along with the posted event source when calling processEvents()
+ // "manually" to prevent livelock deep in CFRunLoop.
+
+ m_timerInfoList.activateTimers();
+ maybeStartCFRunLoopTimer();
+}
+
+void QEventDispatcherCoreFoundation::handleRunLoopActivity(CFRunLoopActivity activity)
+{
+ switch (activity) {
+ case kCFRunLoopBeforeWaiting:
+ emit aboutToBlock();
+ break;
+ case kCFRunLoopAfterWaiting:
+ emit awake();
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+}
+
+bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags)
{
m_interrupted = false;
bool eventsProcessed = false;
+ // The documentation states that this signal is emitted after the event
+ // loop returns from a function that could block, which is not the case
+ // here, but all the other event dispatchers emit awake at the start of
+ // processEvents, and the QEventLoop auto-test has an explicit check for
+ // this behavior, so we assume it's for a good reason and do it as well.
+ emit awake();
+
bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents;
bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec);
bool useExecMode = execFlagSet && !excludeUserEvents;
+ SInt32 result;
+
if (useExecMode) {
- NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
- while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted);
+ while (!m_interrupted) {
+ // Run a single pass on the runloop to unblock it
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, kCFTimeIntervalMinimum, true);
+
+ // Run the default runloop until interrupted (by Qt or UIKit)
+ if (result != kCFRunLoopRunFinished)
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, kCFTimeIntervalDistantFuture, false);
+
+ // App has quit or Qt has interrupted?
+ if (result == kCFRunLoopRunFinished || m_interrupted)
+ break;
+
+ // Runloop was interrupted by UIKit?
+ if (result == kCFRunLoopRunStopped && !m_interrupted) {
+ // Run runloop in UI tracking mode
+ if (CFRunLoopRunInMode((CFStringRef) UITrackingRunLoopMode,
+ kCFTimeIntervalDistantFuture, false) == kCFRunLoopRunFinished)
+ break;
+ }
+ }
eventsProcessed = true;
} else {
if (!(flags & QEventLoop::WaitForMoreEvents))
wakeUp();
- eventsProcessed = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+
+ // Run runloop in default mode
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, kCFTimeIntervalDistantFuture, true);
+ if (result != kCFRunLoopRunFinished) {
+ // Run runloop in UI tracking mode
+ CFRunLoopRunInMode((CFStringRef) UITrackingRunLoopMode, kCFTimeIntervalDistantFuture, false);
+ }
+ eventsProcessed = (result == kCFRunLoopRunHandledSource);
}
return eventsProcessed;
}
-bool QIOSEventDispatcher::hasPendingEvents()
+bool QEventDispatcherCoreFoundation::hasPendingEvents()
{
qDebug() << __FUNCTION__ << "not implemented";
return false;
}
-void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
+void QEventDispatcherCoreFoundation::registerSocketNotifier(QSocketNotifier *notifier)
{
m_cfSocketNotifier.registerSocketNotifier(notifier);
}
-void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
+void QEventDispatcherCoreFoundation::unregisterSocketNotifier(QSocketNotifier *notifier)
{
m_cfSocketNotifier.unregisterSocketNotifier(notifier);
}
-void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)
+void QEventDispatcherCoreFoundation::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)
{
#ifndef QT_NO_DEBUG
if (timerId < 1 || interval < 0 || !obj) {
- qWarning("QIOSEventDispatcher::registerTimer: invalid arguments");
+ qWarning("QEventDispatcherCoreFoundation::registerTimer: invalid arguments");
return;
} else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
- qWarning("QIOSEventDispatcher: timers cannot be started from another thread");
+ qWarning("QEventDispatcherCoreFoundation: timers cannot be started from another thread");
return;
}
#endif
@@ -243,11 +273,11 @@ void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType
maybeStartCFRunLoopTimer();
}
-bool QIOSEventDispatcher::unregisterTimer(int timerId)
+bool QEventDispatcherCoreFoundation::unregisterTimer(int timerId)
{
#ifndef QT_NO_DEBUG
if (timerId < 1) {
- qWarning("QIOSEventDispatcher::unregisterTimer: invalid argument");
+ qWarning("QEventDispatcherCoreFoundation::unregisterTimer: invalid argument");
return false;
} else if (thread() != QThread::currentThread()) {
qWarning("QObject::killTimer: timers cannot be stopped from another thread");
@@ -260,11 +290,11 @@ bool QIOSEventDispatcher::unregisterTimer(int timerId)
return returnValue;
}
-bool QIOSEventDispatcher::unregisterTimers(QObject *object)
+bool QEventDispatcherCoreFoundation::unregisterTimers(QObject *object)
{
#ifndef QT_NO_DEBUG
if (!object) {
- qWarning("QIOSEventDispatcher::unregisterTimers: invalid argument");
+ qWarning("QEventDispatcherCoreFoundation::unregisterTimers: invalid argument");
return false;
} else if (object->thread() != thread() || thread() != QThread::currentThread()) {
qWarning("QObject::killTimers: timers cannot be stopped from another thread");
@@ -277,11 +307,11 @@ bool QIOSEventDispatcher::unregisterTimers(QObject *object)
return returnValue;
}
-QList<QAbstractEventDispatcher::TimerInfo> QIOSEventDispatcher::registeredTimers(QObject *object) const
+QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherCoreFoundation::registeredTimers(QObject *object) const
{
#ifndef QT_NO_DEBUG
if (!object) {
- qWarning("QIOSEventDispatcher:registeredTimers: invalid argument");
+ qWarning("QEventDispatcherCoreFoundation:registeredTimers: invalid argument");
return QList<TimerInfo>();
}
#endif
@@ -289,11 +319,11 @@ QList<QAbstractEventDispatcher::TimerInfo> QIOSEventDispatcher::registeredTimers
return m_timerInfoList.registeredTimers(object);
}
-int QIOSEventDispatcher::remainingTime(int timerId)
+int QEventDispatcherCoreFoundation::remainingTime(int timerId)
{
#ifndef QT_NO_DEBUG
if (timerId < 1) {
- qWarning("QIOSEventDispatcher::remainingTime: invalid argument");
+ qWarning("QEventDispatcherCoreFoundation::remainingTime: invalid argument");
return -1;
}
#endif
@@ -301,19 +331,20 @@ int QIOSEventDispatcher::remainingTime(int timerId)
return m_timerInfoList.timerRemainingTime(timerId);
}
-void QIOSEventDispatcher::wakeUp()
+void QEventDispatcherCoreFoundation::wakeUp()
{
- CFRunLoopSourceSignal(m_postedEventsRunLoopSource);
+ m_postedEventsRunLoopSource.signal();
CFRunLoopWakeUp(CFRunLoopGetMain());
}
-void QIOSEventDispatcher::interrupt()
+void QEventDispatcherCoreFoundation::interrupt()
{
- wakeUp();
+ // Stop the runloop, which will cause processEvents() to exit
m_interrupted = true;
+ CFRunLoopStop(CFRunLoopGetMain());
}
-void QIOSEventDispatcher::flush()
+void QEventDispatcherCoreFoundation::flush()
{
// X11 only.
}
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
index 53a75618ce..e23b8f0ece 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.h
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
@@ -73,8 +73,8 @@
**
****************************************************************************/
-#ifndef QEVENTDISPATCHER_IOS_P_H
-#define QEVENTDISPATCHER_IOS_P_H
+#ifndef QEVENTDISPATCHER_CF_P_H
+#define QEVENTDISPATCHER_CF_P_H
#include <QtCore/qabstracteventdispatcher.h>
#include <QtCore/private/qtimerinfo_unix_p.h>
@@ -83,13 +83,104 @@
QT_BEGIN_NAMESPACE
-class QIOSEventDispatcher : public QAbstractEventDispatcher
+class QEventDispatcherCoreFoundation;
+
+template <class T = QEventDispatcherCoreFoundation>
+class RunLoopSource
+{
+public:
+ typedef void (T::*CallbackFunction) ();
+
+ enum { kHighestPriority = 0 } RunLoopSourcePriority;
+
+ RunLoopSource(T *delegate, CallbackFunction callback)
+ : m_delegate(delegate), m_callback(callback)
+ {
+ CFRunLoopSourceContext context = {};
+ context.info = this;
+ context.perform = RunLoopSource::process;
+
+ m_source = CFRunLoopSourceCreate(kCFAllocatorDefault, kHighestPriority, &context);
+ Q_ASSERT(m_source);
+ }
+
+ ~RunLoopSource()
+ {
+ CFRunLoopSourceInvalidate(m_source);
+ CFRelease(m_source);
+ }
+
+ void addToMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
+ {
+ if (!runLoop)
+ runLoop = CFRunLoopGetCurrent();
+
+ CFRunLoopAddSource(runLoop, m_source, mode);
+ }
+
+ void signal() { CFRunLoopSourceSignal(m_source); }
+
+private:
+ static void process(void *info)
+ {
+ RunLoopSource *self = static_cast<RunLoopSource *>(info);
+ ((self->m_delegate)->*(self->m_callback))();
+ }
+
+ T *m_delegate;
+ CallbackFunction m_callback;
+ CFRunLoopSourceRef m_source;
+};
+
+template <class T = QEventDispatcherCoreFoundation>
+class RunLoopObserver
+{
+public:
+ typedef void (T::*CallbackFunction) (CFRunLoopActivity activity);
+
+ RunLoopObserver(T *delegate, CallbackFunction callback, CFOptionFlags activities)
+ : m_delegate(delegate), m_callback(callback)
+ {
+ CFRunLoopObserverContext context = {};
+ context.info = this;
+
+ m_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, activities, true, 0, process, &context);
+ Q_ASSERT(m_observer);
+ }
+
+ ~RunLoopObserver()
+ {
+ CFRunLoopObserverInvalidate(m_observer);
+ CFRelease(m_observer);
+ }
+
+ void addToMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
+ {
+ if (!runLoop)
+ runLoop = CFRunLoopGetCurrent();
+
+ CFRunLoopAddObserver(runLoop, m_observer, mode);
+ }
+
+private:
+ static void process(CFRunLoopObserverRef, CFRunLoopActivity activity, void *info)
+ {
+ RunLoopObserver *self = static_cast<RunLoopObserver *>(info);
+ ((self->m_delegate)->*(self->m_callback))(activity);
+ }
+
+ T *m_delegate;
+ CallbackFunction m_callback;
+ CFRunLoopObserverRef m_observer;
+};
+
+class QEventDispatcherCoreFoundation : public QAbstractEventDispatcher
{
Q_OBJECT
public:
- explicit QIOSEventDispatcher(QObject *parent = 0);
- ~QIOSEventDispatcher();
+ explicit QEventDispatcherCoreFoundation(QObject *parent = 0);
+ ~QEventDispatcherCoreFoundation();
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
@@ -111,8 +202,10 @@ public:
private:
bool m_interrupted;
- CFRunLoopSourceRef m_postedEventsRunLoopSource;
- CFRunLoopSourceRef m_blockingTimerRunLoopSource;
+ RunLoopSource<> m_postedEventsRunLoopSource;
+ RunLoopSource<> m_blockingTimerRunLoopSource;
+
+ RunLoopObserver<> m_awakeAndBlockObserver;
QTimerInfoList m_timerInfoList;
CFRunLoopTimerRef m_runLoopTimerRef;
@@ -120,14 +213,16 @@ private:
QCFSocketNotifier m_cfSocketNotifier;
void processPostedEvents();
+ void processTimers();
+
void maybeStartCFRunLoopTimer();
void maybeStopCFRunLoopTimer();
- static void postedEventsRunLoopCallback(void *info);
+ void handleRunLoopActivity(CFRunLoopActivity activity);
+
static void nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info);
- static void blockingTimerRunLoopCallback(void *info);
};
QT_END_NAMESPACE
-#endif // QEVENTDISPATCHER_IOS_P_H
+#endif // QEVENTDISPATCHER_CF_P_H
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index afe634dc4b..6b8a82352d 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -317,8 +317,6 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
return stylehint;
}
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
void QFontconfigDatabase::populateFontDatabase()
{
FcFontSet *fonts;
@@ -453,7 +451,7 @@ void QFontconfigDatabase::populateFontDatabase()
// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k)
- qt_registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
}
FcFontSetDestroy (fonts);
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 1e15a9e62c..5139f11d23 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -176,6 +176,10 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
void QCoreTextFontDatabase::populateFontDatabase()
{
+ // The caller (QFontDB) expects the db to be populate only with system fonts, so we need
+ // to make sure that any previously registered app fonts become invisible.
+ removeApplicationFonts();
+
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
@@ -186,82 +190,87 @@ void QCoreTextFontDatabase::populateFontDatabase()
if (! fonts)
return;
- QString foundryName = QLatin1String("CoreText");
const int numFonts = CFArrayGetCount(fonts);
for (int i = 0; i < numFonts; ++i) {
CTFontDescriptorRef font = (CTFontDescriptorRef) CFArrayGetValueAtIndex(fonts, i);
- QCFString familyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL);
- QCFString styleName = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL);
- QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
- QFont::Weight weight = QFont::Normal;
- QFont::Style style = QFont::StyleNormal;
- QFont::Stretch stretch = QFont::Unstretched;
- bool fixedPitch = false;
-
- if (styles) {
- if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
- Q_ASSERT(CFNumberIsFloatType(weightValue));
- double d;
- if (CFNumberGetValue(weightValue, kCFNumberDoubleType, &d))
- weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
- }
- if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
- Q_ASSERT(CFNumberIsFloatType(italic));
- double d;
- if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
- if (d > 0.0)
- style = QFont::StyleItalic;
- }
- }
- if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) {
- int d;
- if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) {
- if (d & kCTFontMonoSpaceTrait)
- fixedPitch = true;
- if (d & kCTFontExpandedTrait)
- stretch = QFont::Expanded;
- else if (d & kCTFontCondensedTrait)
- stretch = QFont::Condensed;
- }
- }
- }
+ populateFromDescriptor(font);
+ }
- int pixelSize = 0;
- if (QCFType<CFNumberRef> size = (CFNumberRef) CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
- if (CFNumberIsFloatType(size)) {
- double d;
- CFNumberGetValue(size, kCFNumberDoubleType, &d);
- pixelSize = d;
- } else {
- CFNumberGetValue(size, kCFNumberIntType, &pixelSize);
+ [pool release];
+}
+
+void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
+{
+ QString foundryName = QStringLiteral("CoreText");
+ QCFString familyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL);
+ QCFString styleName = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL);
+ QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
+ QFont::Weight weight = QFont::Normal;
+ QFont::Style style = QFont::StyleNormal;
+ QFont::Stretch stretch = QFont::Unstretched;
+ bool fixedPitch = false;
+
+ if (styles) {
+ if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
+ Q_ASSERT(CFNumberIsFloatType(weightValue));
+ double d;
+ if (CFNumberGetValue(weightValue, kCFNumberDoubleType, &d))
+ weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
+ }
+ if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
+ Q_ASSERT(CFNumberIsFloatType(italic));
+ double d;
+ if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
+ if (d > 0.0)
+ style = QFont::StyleItalic;
}
}
-
- QSupportedWritingSystems writingSystems;
- if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) {
- CFIndex length = CFArrayGetCount(languages);
- for (int i = 1; i < LanguageCount; ++i) {
- if (!languageForWritingSystem[i])
- continue;
- QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII);
- if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang))
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) {
+ int d;
+ if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) {
+ if (d & kCTFontMonoSpaceTrait)
+ fixedPitch = true;
+ if (d & kCTFontExpandedTrait)
+ stretch = QFont::Expanded;
+ else if (d & kCTFontCondensedTrait)
+ stretch = QFont::Condensed;
}
}
+ }
- CFRetain(font);
- QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch,
- true /* antialiased */, true /* scalable */,
- pixelSize, fixedPitch, writingSystems, (void *) font);
+ int pixelSize = 0;
+ if (QCFType<CFNumberRef> size = (CFNumberRef) CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
+ if (CFNumberIsFloatType(size)) {
+ double d;
+ CFNumberGetValue(size, kCFNumberDoubleType, &d);
+ pixelSize = d;
+ } else {
+ CFNumberGetValue(size, kCFNumberIntType, &pixelSize);
+ }
+ }
- // We need to map back and forth between PostScript-names and family-names for fallback list construction
- CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontNameAttribute);
- psNameToFamily[QCFString::toQString((NSString *) psName)] = familyName;
- familyNameToPsName[familyName] = QCFString::toQString((NSString *) psName);
- CFRelease(psName);
+ QSupportedWritingSystems writingSystems;
+ if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) {
+ CFIndex length = CFArrayGetCount(languages);
+ for (int i = 1; i < LanguageCount; ++i) {
+ if (!languageForWritingSystem[i])
+ continue;
+ QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII);
+ if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
}
- [pool release];
+ CFRetain(font);
+ QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch,
+ true /* antialiased */, true /* scalable */,
+ pixelSize, fixedPitch, writingSystems, (void *) font);
+
+ // We need to map back and forth between PostScript-names and family-names for fallback list construction
+ CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontNameAttribute);
+ psNameToFamily[QCFString::toQString((NSString *) psName)] = familyName;
+ familyNameToPsName[familyName] = QCFString::toQString((NSString *) psName);
+ CFRelease(psName);
}
void QCoreTextFontDatabase::releaseHandle(void *handle)
@@ -473,6 +482,7 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
bool success = CTFontManagerRegisterGraphicsFont(cgFont, &error);
if (success) {
font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
+ m_applicationGraphicsFonts.append(QCFType<CGFontRef>::constructFromGet(cgFont));
} else {
NSLog(@"Unable to register font: %@", error);
CFRelease(error);
@@ -484,12 +494,13 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false);
bool success = CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error);
if (success) {
- const void *keys[] = { fontURL };
- const void *values[] = { kCTFontURLAttribute };
+ const void *keys[] = { kCTFontURLAttribute };
+ const void *values[] = { fontURL };
QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(NULL, keys, values, 1,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
+ m_applicationURLFonts.append(QCFType<CFURLRef>::constructFromGet(fontURL));
} else {
NSLog(@"Unable to register font: %@", error);
CFRelease(error);
@@ -499,6 +510,10 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
if (font) {
QStringList families;
families.append(QCFString(CTFontCopyFamilyName(font)));
+
+ QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
+ populateFromDescriptor(descriptor);
+
CFRelease(font);
return families;
}
@@ -534,9 +549,12 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
QStringList families;
for (int i = 0; i < containedFonts.size(); ++i) {
QCFType<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL);
+ QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
+ populateFromDescriptor(descriptor);
families.append(QCFString(CTFontCopyFamilyName(font)));
}
+ m_applicationFonts.append(fontContainer);
return families;
}
#endif
@@ -569,5 +587,28 @@ QList<int> QCoreTextFontDatabase::standardSizes() const
return ret;
}
+void QCoreTextFontDatabase::removeApplicationFonts()
+{
+#ifdef Q_OS_MACX
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ CFErrorRef error;
+ for (int i = 0; i < m_applicationGraphicsFonts.count(); ++i)
+ CTFontManagerUnregisterGraphicsFont(m_applicationGraphicsFonts[i], &error);
+ m_applicationGraphicsFonts.clear();
+
+ for (int i = 0; i < m_applicationURLFonts.count(); ++i)
+ CTFontManagerUnregisterFontsForURL(m_applicationURLFonts[i], kCTFontManagerScopeProcess, &error);
+ m_applicationURLFonts.clear();
+ }
+#else
+ for (int i = 0; i < m_applicationFonts.count(); ++i)
+ ATSFontDeactivate(m_applicationFonts[i], 0, kATSOptionFlagsDoNotNotify);
+ m_applicationFonts.clear();
+ ATSFontNotify(kATSFontNotifyActionFontsChanged, 0);
+#endif
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index 8536ad9123..c3bb4d428a 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -43,6 +43,14 @@
#define QCORETEXTFONTDATABASE_H
#include <qpa/qplatformfontdatabase.h>
+#include <private/qcore_mac_p.h>
+
+#ifndef Q_OS_IOS
+#include <ApplicationServices/ApplicationServices.h>
+#else
+#include <CoreText/CoreText.h>
+#include <CoreGraphics/CoreGraphics.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -63,9 +71,21 @@ public:
QList<int> standardSizes() const;
private:
+ void populateFromDescriptor(CTFontDescriptorRef font);
+
mutable QString defaultFontName;
mutable QHash<QString, QString> psNameToFamily;
mutable QHash<QString, QString> familyNameToPsName;
+
+ void removeApplicationFonts();
+#ifdef Q_OS_MACX
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+ QVector<QCFType<CGFontRef> > m_applicationGraphicsFonts;
+ QVector<QCFType<CFURLRef> > m_applicationURLFonts;
+#else
+ QVector<ATSFontContainerRef> m_applicationFonts;
+#endif
+#endif
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 8d1c4ed064..9b8f10f588 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -444,18 +444,38 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
}
}
-QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &m)
+static void qcoretextfontengine_scaleMetrics(glyph_metrics_t &br, const QTransform &matrix)
{
- glyph_metrics_t br = boundingBox(glyph);
-
- if (m.isScaling()) {
- qreal hscale = m.m11();
- qreal vscale = m.m22();
+ if (matrix.isScaling()) {
+ qreal hscale = matrix.m11();
+ qreal vscale = matrix.m22();
br.width = QFixed::fromReal(br.width.toReal() * hscale);
br.height = QFixed::fromReal(br.height.toReal() * vscale);
br.x = QFixed::fromReal(br.x.toReal() * hscale);
br.y = QFixed::fromReal(br.y.toReal() * vscale);
}
+}
+
+glyph_metrics_t QCoreTextFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed pos, const QTransform &matrix, GlyphFormat format)
+{
+ if (matrix.type() > QTransform::TxScale)
+ return QFontEngine::alphaMapBoundingBox(glyph, pos, matrix, format);
+
+ glyph_metrics_t br = boundingBox(glyph);
+ qcoretextfontengine_scaleMetrics(br, matrix);
+
+ br.width = qAbs(qRound(br.width)) + 2;
+ br.height = qAbs(qRound(br.height)) + 2;
+
+ return br;
+}
+
+
+QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &m)
+{
+
+ glyph_metrics_t br = boundingBox(glyph);
+ qcoretextfontengine_scaleMetrics(br, m);
bool isColorGlyph = glyphFormat == QFontEngineGlyphCache::Raster_ARGB;
QImage::Format format = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
index a9b1960491..577bb25e95 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
@@ -96,6 +96,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition);
virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t);
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
+ glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat);
virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
virtual qreal minRightBearing() const;
virtual qreal minLeftBearing() const;
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
index d42251d4dd..231576ed01 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
@@ -2242,11 +2242,14 @@ bool AtSpiAdaptor::tableInterface(QAccessibleInterface *interface, const QString
col = index % cols;
QAccessibleTableCellInterface *cell = interface->tableInterface()->cellAt(row, col)->tableCellInterface();
if (cell) {
- cell->rowColumnExtents(&row, &col, &rowExtents, &colExtents, &isSelected);
+ row = cell->rowIndex();
+ col = cell->columnIndex();
+ rowExtents = cell->rowExtent();
+ colExtents = cell->columnExtent();
+ isSelected = cell->isSelected();
success = true;
}
}
-
QVariantList list;
list << success << row << col << rowExtents << colExtents << isSelected;
connection.send(message.createReply(list));
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
index fedaa3a655..77ea0f1db8 100644
--- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
@@ -54,16 +54,24 @@ enum { debug = 0 };
static inline QByteArray detectDesktopEnvironment()
{
- if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
- return QByteArray("KDE");
- // Check Unity first, whose older versions also have "GNOME_DESKTOP_SESSION_ID" set.
const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
- if (xdgCurrentDesktop == "Unity")
- return QByteArrayLiteral("UNITY");
- // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
- if (qgetenv("DESKTOP_SESSION") == "gnome" || !qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
- return QByteArray("GNOME");
- return QByteArray("UNKNOWN");
+ if (!xdgCurrentDesktop.isEmpty())
+ return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE...
+
+ // Classic fallbacks
+ if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
+ return QByteArrayLiteral("KDE");
+ if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
+ return QByteArrayLiteral("GNOME");
+
+ // Fallback to checking $DESKTOP_SESSION (unreliable)
+ const QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
+ if (desktopSession == "gnome")
+ return QByteArrayLiteral("GNOME");
+ if (desktopSession == "xfce")
+ return QByteArrayLiteral("XFCE");
+
+ return QByteArrayLiteral("UNKNOWN");
}
static inline bool checkExecutable(const QString &candidate, QString *result)
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index fdd45a49c5..ee295afe6c 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -58,20 +58,22 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
ResourceHelper::ResourceHelper()
{
- qFill(palettes, palettes + QPlatformTheme::NPalettes, static_cast<QPalette *>(0));
- qFill(fonts, fonts + QPlatformTheme::NFonts, static_cast<QFont *>(0));
+ std::fill(palettes, palettes + QPlatformTheme::NPalettes, static_cast<QPalette *>(0));
+ std::fill(fonts, fonts + QPlatformTheme::NFonts, static_cast<QFont *>(0));
}
void ResourceHelper::clear()
{
qDeleteAll(palettes, palettes + QPlatformTheme::NPalettes);
qDeleteAll(fonts, fonts + QPlatformTheme::NFonts);
- qFill(palettes, palettes + QPlatformTheme::NPalettes, static_cast<QPalette *>(0));
- qFill(fonts, fonts + QPlatformTheme::NFonts, static_cast<QFont *>(0));
+ std::fill(palettes, palettes + QPlatformTheme::NPalettes, static_cast<QPalette *>(0));
+ std::fill(fonts, fonts + QPlatformTheme::NFonts, static_cast<QFont *>(0));
}
/*!
@@ -95,9 +97,13 @@ public:
QGenericUnixThemePrivate()
: QPlatformThemePrivate()
, systemFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize)
- { }
+ , fixedFont(QStringLiteral("monospace"), systemFont.pointSize())
+ {
+ fixedFont.setStyleHint(QFont::TypeWriter);
+ }
const QFont systemFont;
+ QFont fixedFont;
};
QGenericUnixTheme::QGenericUnixTheme()
@@ -108,9 +114,14 @@ QGenericUnixTheme::QGenericUnixTheme()
const QFont *QGenericUnixTheme::font(Font type) const
{
Q_D(const QGenericUnixTheme);
- if (type == QPlatformTheme::SystemFont)
+ switch (type) {
+ case QPlatformTheme::SystemFont:
return &d->systemFont;
- return 0;
+ case QPlatformTheme::FixedFont:
+ return &d->fixedFont;
+ default:
+ return 0;
+ }
}
// Helper to return the icon theme paths from XDG.
@@ -240,11 +251,18 @@ void QKdeThemePrivate::refresh()
toolButtonStyle = Qt::ToolButtonTextUnderIcon;
}
- // Read system font, ignore 'fixed' 'smallestReadableFont'
- if (QFont *systemFont = readKdeFontSetting(kdeSettings, QStringLiteral("font"))) {
+ // Read system font, ignore 'smallestReadableFont'
+ if (QFont *systemFont = readKdeFontSetting(kdeSettings, QStringLiteral("font")))
resources.fonts[QPlatformTheme::SystemFont] = systemFont;
- } else {
+ else
resources.fonts[QPlatformTheme::SystemFont] = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
+
+ if (QFont *fixedFont = readKdeFontSetting(kdeSettings, QStringLiteral("fixed"))) {
+ resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
+ } else {
+ fixedFont = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
+ fixedFont->setStyleHint(QFont::TypeWriter);
+ resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
}
}
@@ -461,9 +479,13 @@ class QGnomeThemePrivate : public QPlatformThemePrivate
public:
QGnomeThemePrivate()
: systemFont(QLatin1Literal(defaultSystemFontNameC), defaultSystemFontSize)
- {}
+ , fixedFont(QStringLiteral("monospace"), systemFont.pointSize())
+ {
+ fixedFont.setStyleHint(QFont::TypeWriter);
+ }
const QFont systemFont;
+ QFont fixedFont;
};
QGnomeTheme::QGnomeTheme()
@@ -501,10 +523,14 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
const QFont *QGnomeTheme::font(Font type) const
{
Q_D(const QGnomeTheme);
- if (type == QPlatformTheme::SystemFont)
- return &d->systemFont;
-
- return 0;
+ switch (type) {
+ case QPlatformTheme::SystemFont:
+ return &d->systemFont;
+ case QPlatformTheme::FixedFont:
+ return &d->fixedFont;
+ default:
+ return 0;
+ }
}
/*!
@@ -534,7 +560,11 @@ QStringList QGenericUnixTheme::themeNames()
#ifndef QT_NO_SETTINGS
result.push_back(QLatin1String(QKdeTheme::name));
#endif
- } else { // Gnome, Unity, other Gtk-based desktops like XFCE.
+ } else if (desktopEnvironment == QByteArrayLiteral("GNOME") ||
+ desktopEnvironment == QByteArrayLiteral("UNITY") ||
+ desktopEnvironment == QByteArrayLiteral("MATE") ||
+ desktopEnvironment == QByteArrayLiteral("XFCE") ||
+ desktopEnvironment == QByteArrayLiteral("LXDE")) { // Gtk-based desktops
// prefer the GTK2 theme implementation with native dialogs etc.
result.push_back(QStringLiteral("gtk2"));
// fallback to the generic Gnome theme if loading the GTK2 theme fails
diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp
index d460ec2c98..86c7812553 100644
--- a/src/plugins/accessible/widgets/itemviews.cpp
+++ b/src/plugins/accessible/widgets/itemviews.cpp
@@ -1010,15 +1010,6 @@ void QAccessibleTableCell::unselectCell()
view->selectionModel()->select(m_index, QItemSelectionModel::Deselect);
}
-void QAccessibleTableCell::rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const
-{
- *row = m_index.row();
- *column = m_index.column();
- *rowExtents = 1;
- *columnExtents = 1;
- *selected = isSelected();
-}
-
QAccessibleInterface *QAccessibleTableCell::table() const
{
return QAccessible::queryAccessibleInterface(view);
diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h
index 09dacde7a2..72b2339dd3 100644
--- a/src/plugins/accessible/widgets/itemviews.h
+++ b/src/plugins/accessible/widgets/itemviews.h
@@ -194,7 +194,6 @@ public:
virtual QList<QAccessibleInterface*> rowHeaderCells() const;
virtual int rowIndex() const;
virtual bool isSelected() const;
- virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const;
virtual QAccessibleInterface* table() const;
//action interface
diff --git a/src/plugins/bearer/blackberry/qbbengine.cpp b/src/plugins/bearer/blackberry/qbbengine.cpp
index ab1ba9aa19..37093a09ec 100644
--- a/src/plugins/bearer/blackberry/qbbengine.cpp
+++ b/src/plugins/bearer/blackberry/qbbengine.cpp
@@ -98,10 +98,9 @@ interfaceType(netstatus_interface_type_t type)
return QNetworkConfiguration::BearerBluetooth;
case NETSTATUS_INTERFACE_TYPE_CELLULAR:
- //### TODO not sure which BearerType would be the best
- //to return here. We need to be able to get more
- //information on the bearer type in order to return
- //the exact match.
+ // The exact bearer type is determined in QNetworkConfiguration
+ // at the time this info is queried, because opposed to the
+ // information here the type might change quickly.
return QNetworkConfiguration::Bearer2G;
case NETSTATUS_INTERFACE_TYPE_VPN:
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 116c6cfa7d..c222b62a36 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -47,6 +47,8 @@
#include <QtCore/QStringList>
#include <QtCore/QString>
+#include <algorithm>
+
#include <xkbcommon/xkbcommon.h>
#ifdef XKBCOMMON_0_2_0
@@ -445,6 +447,6 @@ void TableGenerator::orderComposeTable()
// Stable-sorting to ensure that the item that appeared before the other in the
// original container will still appear first after the sort. This property is
// needed to handle the cases when user re-defines already defined key sequence
- qStableSort(m_composeTable.begin(), m_composeTable.end(), Compare());
+ std::stable_sort(m_composeTable.begin(), m_composeTable.end(), Compare());
}
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
index 611b9fdd9b..65b93b1a45 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
@@ -45,6 +45,8 @@
#include <QtGui/QKeyEvent>
#include <QtCore/QDebug>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
//#define DEBUG_COMPOSING
@@ -170,7 +172,7 @@ static bool isDuplicate(const QComposeTableElement &lhs, const QComposeTableElem
bool QComposeInputContext::checkComposeTable()
{
QVector<QComposeTableElement>::const_iterator it =
- qLowerBound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, Compare());
+ std::lower_bound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, Compare());
// prevent dereferencing an 'end' iterator, which would result in a crash
if (it == m_composeTable.constEnd())
diff --git a/src/plugins/platforminputcontexts/maliit/contextadaptor.cpp b/src/plugins/platforminputcontexts/maliit/contextadaptor.cpp
deleted file mode 100644
index 134ff94f6b..0000000000
--- a/src/plugins/platforminputcontexts/maliit/contextadaptor.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "contextadaptor.h"
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMetaObject>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-
-#include "qmaliitplatforminputcontext.h"
-
-/*
- * Implementation of adaptor class Inputcontext1Adaptor
- */
-
-Inputcontext1Adaptor::Inputcontext1Adaptor(QObject *parent)
- : QDBusAbstractAdaptor(parent)
-{
- // constructor
- setAutoRelaySignals(true);
-}
-
-Inputcontext1Adaptor::~Inputcontext1Adaptor()
-{
- // destructor
-}
-
-void Inputcontext1Adaptor::activationLostEvent()
-{
- // handle method call com.meego.inputmethod.inputcontext1.activationLostEvent
- QMetaObject::invokeMethod(parent(), "activationLostEvent");
-}
-
-void Inputcontext1Adaptor::commitString(const QString &in0, int in1, int in2, int in3)
-{
- // handle method call com.meego.inputmethod.inputcontext1.commitString
- QMetaObject::invokeMethod(parent(), "commitString", Q_ARG(QString, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(int, in3));
-}
-
-void Inputcontext1Adaptor::updatePreedit(const QDBusMessage &message)
-{
- // handle method call com.meego.inputmethod.inputcontext1.updatePreedit
- QMetaObject::invokeMethod(parent(), "updatePreedit", Q_ARG(QDBusMessage, message));
-}
-
-void Inputcontext1Adaptor::copy()
-{
- // handle method call com.meego.inputmethod.inputcontext1.copy
- QMetaObject::invokeMethod(parent(), "copy");
-}
-
-void Inputcontext1Adaptor::imInitiatedHide()
-{
- // handle method call com.meego.inputmethod.inputcontext1.imInitiatedHide
- QMetaObject::invokeMethod(parent(), "imInitiatedHide");
-}
-
-void Inputcontext1Adaptor::keyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uchar in6)
-{
- // handle method call com.meego.inputmethod.inputcontext1.keyEvent
- QMetaObject::invokeMethod(parent(), "keyEvent", Q_ARG(int, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(QString, in3), Q_ARG(bool, in4), Q_ARG(int, in5), Q_ARG(uchar, in6));
-}
-
-void Inputcontext1Adaptor::paste()
-{
- // handle method call com.meego.inputmethod.inputcontext1.paste
- QMetaObject::invokeMethod(parent(), "paste");
-}
-
-bool Inputcontext1Adaptor::preeditRectangle(int &out1, int &out2, int &out3, int &out4)
-{
- // handle method call com.meego.inputmethod.inputcontext1.preeditRectangle
- return static_cast<QMaliitPlatformInputContext *>(parent())->preeditRectangle(out1, out2, out3, out4);
-}
-
-bool Inputcontext1Adaptor::selection(QString &out1)
-{
- // handle method call com.meego.inputmethod.inputcontext1.selection
- return static_cast<QMaliitPlatformInputContext *>(parent())->selection(out1);
-}
-
-void Inputcontext1Adaptor::setDetectableAutoRepeat(bool in0)
-{
- // handle method call com.meego.inputmethod.inputcontext1.setDetectableAutoRepeat
- QMetaObject::invokeMethod(parent(), "setDetectableAutoRepeat", Q_ARG(bool, in0));
-}
-
-void Inputcontext1Adaptor::setGlobalCorrectionEnabled(bool in0)
-{
- // handle method call com.meego.inputmethod.inputcontext1.setGlobalCorrectionEnabled
- QMetaObject::invokeMethod(parent(), "setGlobalCorrectionEnabled", Q_ARG(bool, in0));
-}
-
-void Inputcontext1Adaptor::setLanguage(const QString &in0)
-{
- // handle method call com.meego.inputmethod.inputcontext1.setLanguage
- QMetaObject::invokeMethod(parent(), "setLanguage", Q_ARG(QString, in0));
-}
-
-void Inputcontext1Adaptor::setRedirectKeys(bool in0)
-{
- // handle method call com.meego.inputmethod.inputcontext1.setRedirectKeys
- QMetaObject::invokeMethod(parent(), "setRedirectKeys", Q_ARG(bool, in0));
-}
-
-void Inputcontext1Adaptor::setSelection(int in0, int in1)
-{
- // handle method call com.meego.inputmethod.inputcontext1.setSelection
- QMetaObject::invokeMethod(parent(), "setSelection", Q_ARG(int, in0), Q_ARG(int, in1));
-}
-
-void Inputcontext1Adaptor::updateInputMethodArea(int in0, int in1, int in2, int in3)
-{
- // handle method call com.meego.inputmethod.inputcontext1.updateInputMethodArea
- QMetaObject::invokeMethod(parent(), "updateInputMethodArea", Q_ARG(int, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(int, in3));
-}
-
diff --git a/src/plugins/platforminputcontexts/maliit/contextadaptor.h b/src/plugins/platforminputcontexts/maliit/contextadaptor.h
deleted file mode 100644
index e959a7cb5b..0000000000
--- a/src/plugins/platforminputcontexts/maliit/contextadaptor.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef CONTEXT_H_1318935171
-#define CONTEXT_H_1318935171
-
-#include <QtCore/QObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-#include <QtDBus/QtDBus>
-
-/*
- * Adaptor class for interface com.meego.inputmethod.inputcontext1
- */
-class Inputcontext1Adaptor: public QDBusAbstractAdaptor
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "com.meego.inputmethod.inputcontext1")
- Q_CLASSINFO("D-Bus Introspection", ""
-" <interface name=\"com.meego.inputmethod.inputcontext1\">\n"
-" <method name=\"activationLostEvent\"/>\n"
-" <method name=\"imInitiatedHide\"/>\n"
-" <method name=\"commitString\">\n"
-" <arg type=\"s\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" </method>\n"
-" <method name=\"updatePreedit\">\n"
-" <arg type=\"s\"/>\n"
-" <arg type=\"a(iii)\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" </method>\n"
-" <method name=\"keyEvent\">\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"s\"/>\n"
-" <arg type=\"b\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"y\"/>\n"
-" </method>\n"
-" <method name=\"updateInputMethodArea\">\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" </method>\n"
-" <method name=\"setGlobalCorrectionEnabled\">\n"
-" <arg type=\"b\"/>\n"
-" </method>\n"
-" <method name=\"preeditRectangle\">\n"
-" <arg direction=\"out\" type=\"b\"/>\n"
-" <arg direction=\"out\" type=\"i\"/>\n"
-" <arg direction=\"out\" type=\"i\"/>\n"
-" <arg direction=\"out\" type=\"i\"/>\n"
-" <arg direction=\"out\" type=\"i\"/>\n"
-" </method>\n"
-" <method name=\"copy\"/>\n"
-" <method name=\"paste\"/>\n"
-" <method name=\"setRedirectKeys\">\n"
-" <arg type=\"b\"/>\n"
-" </method>\n"
-" <method name=\"setDetectableAutoRepeat\">\n"
-" <arg type=\"b\"/>\n"
-" </method>\n"
-" <method name=\"setSelection\">\n"
-" <arg type=\"i\"/>\n"
-" <arg type=\"i\"/>\n"
-" </method>\n"
-" <method name=\"selection\">\n"
-" <arg direction=\"out\" type=\"b\"/>\n"
-" <arg direction=\"out\" type=\"s\"/>\n"
-" </method>\n"
-" <method name=\"setLanguage\">\n"
-" <arg type=\"s\"/>\n"
-" </method>\n"
-" </interface>\n"
- "")
-public:
- Inputcontext1Adaptor(QObject *parent);
- virtual ~Inputcontext1Adaptor();
-
-public: // PROPERTIES
-public Q_SLOTS: // METHODS
- void activationLostEvent();
- void commitString(const QString &in0, int in1, int in2, int in3);
- void updatePreedit(const QDBusMessage &message);
- void copy();
- void imInitiatedHide();
- void keyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uchar in6);
- void paste();
- bool preeditRectangle(int &out1, int &out2, int &out3, int &out4);
- bool selection(QString &out1);
- void setDetectableAutoRepeat(bool in0);
- void setGlobalCorrectionEnabled(bool in0);
- void setLanguage(const QString &in0);
- void setRedirectKeys(bool in0);
- void setSelection(int in0, int in1);
- void updateInputMethodArea(int in0, int in1, int in2, int in3);
-Q_SIGNALS: // SIGNALS
-};
-
-#endif
diff --git a/src/plugins/platforminputcontexts/maliit/maliit.json b/src/plugins/platforminputcontexts/maliit/maliit.json
deleted file mode 100644
index f828e1426e..0000000000
--- a/src/plugins/platforminputcontexts/maliit/maliit.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "maliit" ]
-}
diff --git a/src/plugins/platforminputcontexts/maliit/maliit.pro b/src/plugins/platforminputcontexts/maliit/maliit.pro
deleted file mode 100644
index 1e50f7289b..0000000000
--- a/src/plugins/platforminputcontexts/maliit/maliit.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TARGET = maliitplatforminputcontextplugin
-
-PLUGIN_TYPE = platforminputcontexts
-PLUGIN_CLASS_NAME = QMaliitPlatformInputContextPlugin
-load(qt_plugin)
-
-QT += dbus gui-private
-SOURCES += $$PWD/qmaliitplatforminputcontext.cpp \
- $$PWD/serverproxy.cpp \
- $$PWD/serveraddressproxy.cpp \
- $$PWD/contextadaptor.cpp \
- $$PWD/main.cpp
-
-HEADERS += $$PWD/qmaliitplatforminputcontext.h \
- $$PWD/serverproxy.h \
- $$PWD/serveraddressproxy.h \
- $$PWD/contextadaptor.h
-
-OTHER_FILES += $$PWD/maliit.json
diff --git a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp
deleted file mode 100644
index 6d748d44a1..0000000000
--- a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qmaliitplatforminputcontext.h"
-
-#include <QtDebug>
-#include <QTextCharFormat>
-#include <QGuiApplication>
-#include <qwindow.h>
-#include <qevent.h>
-#include <qscreen.h>
-
-#include "serveraddressproxy.h"
-#include "serverproxy.h"
-#include "contextadaptor.h"
-
-#include <sys/types.h>
-#include <signal.h>
-
-#include <QtDBus>
-
-QT_BEGIN_NAMESPACE
-
-enum { debug = 0 };
-
-enum InputPanelVisibility {
- InputPanelHidden,
- InputPanelShowRequested,
- InputPanelShown
-};
-
-enum MaliitOrientationAngle {
- Angle0 = 0,
- Angle90 = 90,
- Angle180 = 180,
- Angle270 = 270
-};
-
-static int orientationAngle(Qt::ScreenOrientation orientation)
-{
- switch (orientation) {
- case Qt::PrimaryOrientation: // Urgh.
- case Qt::PortraitOrientation:
- return Angle270;
- case Qt::LandscapeOrientation:
- return Angle0;
- case Qt::InvertedPortraitOrientation:
- return Angle90;
- case Qt::InvertedLandscapeOrientation:
- return Angle180;
- }
- return Angle0;
-}
-
-// From MTF:
-//! Content type for text entries. Used at least with MTextEdit
-enum TextContentType {
- //! all characters allowed
- FreeTextContentType,
-
- //! only integer numbers allowed
- NumberContentType,
-
- //! allows numbers and certain other characters used in phone numbers
- PhoneNumberContentType,
-
- //! allows only characters permitted in email address
- EmailContentType,
-
- //! allows only character permitted in URL address
- UrlContentType,
-
- //! allows content with user defined format
- CustomContentType
-};
-static TextContentType contentTypeFromHints(Qt::InputMethodHints hints)
-{
- TextContentType type = FreeTextContentType;
- hints &= Qt::ImhExclusiveInputMask;
-
- if (hints == Qt::ImhFormattedNumbersOnly || hints == Qt::ImhDigitsOnly)
- type = NumberContentType;
- else if (hints == Qt::ImhDialableCharactersOnly)
- type = PhoneNumberContentType;
- else if (hints == Qt::ImhEmailCharactersOnly)
- type = EmailContentType;
- else if (hints == Qt::ImhUrlCharactersOnly)
- type = UrlContentType;
-
- return type;
-}
-
-/// From Maliit's namespace.h
-enum MaliitEventRequestType {
- EventRequestBoth, //!< Both a Qt::KeyEvent and a signal
- EventRequestSignalOnly, //!< Only a signal
- EventRequestEventOnly //!< Only a Qt::KeyEvent
-};
-
-static QString maliitServerAddress()
-{
- org::maliit::Server::Address serverAddress(QStringLiteral("org.maliit.server"), QStringLiteral("/org/maliit/server/address"), QDBusConnection::sessionBus());
-
- QString address(serverAddress.address());
-
- // Fallback to old socket when org.maliit.server service is not available
- if (address.isEmpty())
- return QStringLiteral("unix:path=/tmp/meego-im-uiserver/imserver_dbus");
-
- return address;
-}
-
-class QMaliitPlatformInputContextPrivate
-{
-public:
- QMaliitPlatformInputContextPrivate(QMaliitPlatformInputContext *qq);
- ~QMaliitPlatformInputContextPrivate()
- {
- delete adaptor;
- delete server;
- }
-
- void sendStateUpdate(bool focusChanged = false);
-
- QDBusConnection connection;
- ComMeegoInputmethodUiserver1Interface *server;
- Inputcontext1Adaptor *adaptor;
-
- QMap<QString, QVariant> imState;
-
- InputPanelVisibility visibility;
-
- bool valid;
- bool active;
- bool correctionEnabled;
- QRect keyboardRect;
- QString preedit;
- QPointer<QWindow> window;
- QMaliitPlatformInputContext *q;
-};
-
-
-QMaliitPlatformInputContext::QMaliitPlatformInputContext()
- : d(new QMaliitPlatformInputContextPrivate(this))
-{
- if (debug)
- qDebug() << "QMaliitPlatformInputContext::QMaliitPlatformInputContext()";
-}
-
-QMaliitPlatformInputContext::~QMaliitPlatformInputContext(void)
-{
- delete d;
-}
-
-bool QMaliitPlatformInputContext::isValid() const
-{
- return d->valid;
-}
-
-void QMaliitPlatformInputContext::invokeAction(QInputMethod::Action action, int x)
-{
- if (!inputMethodAccepted())
- return;
-
- if (action == QInputMethod::Click) {
- if (x < 0 || x >= d->preedit.length()) {
- reset();
- return;
- }
-
- d->imState["preeditClickPos"] = x;
- d->sendStateUpdate();
- // The first argument is the mouse pos and the second is the
- // preedit rectangle. Both are unused on the server side.
- d->server->mouseClickedOnPreedit(0, 0, 0, 0, 0, 0);
- } else {
- QPlatformInputContext::invokeAction(action, x);
- }
-}
-
-void QMaliitPlatformInputContext::reset()
-{
- const bool hadPreedit = !d->preedit.isEmpty();
- if (hadPreedit && inputMethodAccepted()) {
- // ### selection
- QInputMethodEvent event;
- event.setCommitString(d->preedit);
- QGuiApplication::sendEvent(qGuiApp->focusObject(), &event);
- d->preedit.clear();
- }
-
- QDBusPendingReply<void> reply = d->server->reset();
- if (hadPreedit)
- reply.waitForFinished();
-}
-
-void QMaliitPlatformInputContext::update(Qt::InputMethodQueries queries)
-{
- if (!qGuiApp->focusObject())
- return;
-
- QInputMethodQueryEvent query(queries);
- QGuiApplication::sendEvent(qGuiApp->focusObject(), &query);
-
- if (queries & Qt::ImSurroundingText)
- d->imState["surroundingText"] = query.value(Qt::ImSurroundingText);
- if (queries & Qt::ImCursorPosition)
- d->imState["cursorPosition"] = query.value(Qt::ImCursorPosition);
- if (queries & Qt::ImAnchorPosition)
- d->imState["anchorPosition"] = query.value(Qt::ImAnchorPosition);
- if (queries & Qt::ImCursorRectangle) {
- QRect rect = query.value(Qt::ImCursorRectangle).toRect();
- rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(rect);
- QWindow *window = qGuiApp->focusWindow();
- if (window)
- d->imState["cursorRectangle"] = QRect(window->mapToGlobal(rect.topLeft()), rect.size());
- }
-
- if (queries & Qt::ImCurrentSelection)
- d->imState["hasSelection"] = !query.value(Qt::ImCurrentSelection).toString().isEmpty();
-
- if (queries & Qt::ImHints) {
- Qt::InputMethodHints hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt());
-
- d->imState["predictionEnabled"] = !(hints & Qt::ImhNoPredictiveText);
- d->imState["autocapitalizationEnabled"] = !(hints & Qt::ImhNoAutoUppercase);
- d->imState["hiddenText"] = (hints & Qt::ImhHiddenText) != 0;
-
- d->imState["contentType"] = contentTypeFromHints(hints);
- }
-
- d->sendStateUpdate(/*focusChanged*/true);
-}
-
-QRectF QMaliitPlatformInputContext::keyboardRect() const
-{
- return d->keyboardRect;
-}
-
-void QMaliitPlatformInputContext::activationLostEvent()
-{
- d->active = false;
- d->visibility = InputPanelHidden;
-}
-
-void QMaliitPlatformInputContext::commitString(const QString &string, int replacementStart, int replacementLength, int /* cursorPos */)
-{
- if (!inputMethodAccepted())
- return;
-
- d->preedit.clear();
-
- if (debug)
- qWarning() << "CommitString" << string;
- // ### start/cursorPos
- QInputMethodEvent event;
- event.setCommitString(string, replacementStart, replacementLength);
- QCoreApplication::sendEvent(qGuiApp->focusObject(), &event);
-}
-
-void QMaliitPlatformInputContext::updatePreedit(const QDBusMessage &message)
-{
- if (!inputMethodAccepted())
- return;
-
- QList<QVariant> arguments = message.arguments();
- if (arguments.count() != 5) {
- qWarning() << "QMaliitPlatformInputContext::updatePreedit: Received message from input method server with wrong parameters.";
- return;
- }
-
- d->preedit = arguments[0].toString();
-
- QList<QInputMethodEvent::Attribute> attributes;
-
- const QDBusArgument formats = arguments[1].value<QDBusArgument>();
- formats.beginArray();
- while (!formats.atEnd()) {
- formats.beginStructure();
- int start, length, preeditFace;
- formats >> start >> length >> preeditFace;
- formats.endStructure();
-
- QTextCharFormat format;
-
- enum PreeditFace {
- PreeditDefault,
- PreeditNoCandidates,
- PreeditKeyPress, //!< Used for displaying the hwkbd key just pressed
- PreeditUnconvertible, //!< Inactive preedit region, not clickable
- PreeditActive, //!< Preedit region with active suggestions
-
- };
- switch (PreeditFace(preeditFace)) {
- case PreeditDefault:
- case PreeditKeyPress:
- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- format.setUnderlineColor(QColor(0, 0, 0));
- break;
- case PreeditNoCandidates:
- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- format.setUnderlineColor(QColor(255, 0, 0));
- break;
- case PreeditUnconvertible:
- format.setForeground(QBrush(QColor(128, 128, 128)));
- break;
- case PreeditActive:
- format.setForeground(QBrush(QColor(153, 50, 204)));
- format.setFontWeight(QFont::Bold);
- break;
- default:
- break;
- }
-
- attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, format);
- }
- formats.endArray();
-
- int replacementStart = arguments[2].toInt();
- int replacementLength = arguments[3].toInt();
- int cursorPos = arguments[4].toInt();
-
- if (debug)
- qWarning() << "updatePreedit" << d->preedit << replacementStart << replacementLength << cursorPos;
-
- if (cursorPos >= 0)
- attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, 1, QVariant());
-
- QInputMethodEvent event(d->preedit, attributes);
- if (replacementStart || replacementLength)
- event.setCommitString(QString(), replacementStart, replacementLength);
- QCoreApplication::sendEvent(qGuiApp->focusObject(), &event);
-}
-
-void QMaliitPlatformInputContext::copy()
-{
- // Not supported at the moment.
-}
-
-void QMaliitPlatformInputContext::imInitiatedHide()
-{
- d->visibility = InputPanelHidden;
- emitInputPanelVisibleChanged();
- // ### clear focus
-}
-
-void QMaliitPlatformInputContext::keyEvent(int type, int key, int modifiers, const QString &text,
- bool autoRepeat, int count, uchar requestType_)
-{
- MaliitEventRequestType requestType = MaliitEventRequestType(requestType_);
- if (requestType == EventRequestSignalOnly) {
- qWarning() << "Maliit: Signal emitted key events are not supported.";
- return;
- }
-
- // HACK: This code relies on QEvent::Type for key events and modifiers to be binary compatible between
- // Qt 4 and 5.
- QEvent::Type eventType = static_cast<QEvent::Type>(type);
- if (type != QEvent::KeyPress && type != QEvent::KeyRelease) {
- qWarning() << "Maliit: Unknown key event type" << type;
- return;
- }
-
- QKeyEvent event(eventType, key, static_cast<Qt::KeyboardModifiers>(modifiers),
- text, autoRepeat, count);
- if (d->window)
- QCoreApplication::sendEvent(d->window.data(), &event);
-}
-
-void QMaliitPlatformInputContext::paste()
-{
- // Not supported at the moment.
-}
-
-bool QMaliitPlatformInputContext::preeditRectangle(int &x, int &y, int &width, int &height)
-{
- // ###
- QRect r = qApp->inputMethod()->cursorRectangle().toRect();
- if (!r.isValid())
- return false;
- x = r.x();
- y = r.y();
- width = r.width();
- height = r.height();
- return true;
-}
-
-bool QMaliitPlatformInputContext::selection(QString &selection)
-{
- selection.clear();
-
- if (!inputMethodAccepted())
- return false;
-
- QInputMethodQueryEvent query(Qt::ImCurrentSelection);
- QGuiApplication::sendEvent(qGuiApp->focusObject(), &query);
- QVariant value = query.value(Qt::ImCurrentSelection);
- if (!value.isValid())
- return false;
-
- selection = value.toString();
- return true;
-}
-
-void QMaliitPlatformInputContext::setDetectableAutoRepeat(bool)
-{
- // Not supported.
-}
-
-void QMaliitPlatformInputContext::setGlobalCorrectionEnabled(bool enable)
-{
- d->correctionEnabled = enable;
-}
-
-void QMaliitPlatformInputContext::setLanguage(const QString &)
-{
- // Unused at the moment.
-}
-
-void QMaliitPlatformInputContext::setRedirectKeys(bool)
-{
- // Not supported.
-}
-
-void QMaliitPlatformInputContext::setSelection(int start, int length)
-{
- if (!inputMethodAccepted())
- return;
-
- QList<QInputMethodEvent::Attribute> attributes;
- attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, start, length, QVariant());
- QInputMethodEvent event(QString(), attributes);
- QGuiApplication::sendEvent(qGuiApp->focusObject(), &event);
-}
-
-void QMaliitPlatformInputContext::updateInputMethodArea(int x, int y, int width, int height)
-{
- d->keyboardRect = QRect(x, y, width, height);
- emitKeyboardRectChanged();
-}
-
-void QMaliitPlatformInputContext::updateServerWindowOrientation(Qt::ScreenOrientation orientation)
-{
- d->server->appOrientationChanged(orientationAngle(orientation));
-}
-
-void QMaliitPlatformInputContext::setFocusObject(QObject *object)
-{
- if (!d->valid)
- return;
-
- QWindow *window = qGuiApp->focusWindow();
- if (window != d->window.data()) {
- if (d->window)
- disconnect(d->window.data(), SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)),
- this, SLOT(updateServerWindowOrientation(Qt::ScreenOrientation)));
- d->window = window;
- if (d->window)
- connect(d->window.data(), SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)),
- this, SLOT(updateServerWindowOrientation(Qt::ScreenOrientation)));
- }
-
- d->imState["focusState"] = (object != 0);
- if (inputMethodAccepted()) {
- if (window)
- d->imState["winId"] = static_cast<qulonglong>(window->winId());
-
- if (!d->active) {
- d->active = true;
- d->server->activateContext();
-
- if (window)
- d->server->appOrientationChanged(orientationAngle(window->contentOrientation()));
- }
- }
- d->sendStateUpdate(/*focusChanged*/true);
- if (inputMethodAccepted() && window && d->visibility == InputPanelShowRequested)
- showInputPanel();
-}
-
-void QMaliitPlatformInputContext::showInputPanel()
-{
- if (debug)
- qDebug() << "showInputPanel";
-
- if (!inputMethodAccepted())
- d->visibility = InputPanelShowRequested;
- else {
- d->server->showInputMethod();
- d->visibility = InputPanelShown;
- emitInputPanelVisibleChanged();
- }
-}
-
-void QMaliitPlatformInputContext::hideInputPanel()
-{
- d->server->hideInputMethod();
- d->visibility = InputPanelHidden;
- emitInputPanelVisibleChanged();
-}
-
-bool QMaliitPlatformInputContext::isInputPanelVisible() const
-{
- return d->visibility == InputPanelShown;
-}
-
-QMaliitPlatformInputContextPrivate::QMaliitPlatformInputContextPrivate(QMaliitPlatformInputContext* qq)
- : connection(QDBusConnection::connectToPeer(maliitServerAddress(), QLatin1String("MaliitIMProxy")))
- , server(0)
- , adaptor(0)
- , visibility(InputPanelHidden)
- , valid(false)
- , active(false)
- , correctionEnabled(false)
- , q(qq)
-{
- if (!connection.isConnected())
- return;
-
- server = new ComMeegoInputmethodUiserver1Interface(QStringLiteral(""), QStringLiteral("/com/meego/inputmethod/uiserver1"), connection);
- adaptor = new Inputcontext1Adaptor(qq);
- connection.registerObject("/com/meego/inputmethod/inputcontext", qq);
-
- enum InputMethodMode {
- //! Normal mode allows to use preedit and error correction
- InputMethodModeNormal,
-
- //! Virtual keyboard sends QKeyEvent for every key press or release
- InputMethodModeDirect,
-
- //! Used with proxy widget
- InputMethodModeProxy
- };
- imState["inputMethodMode"] = InputMethodModeNormal;
-
- imState["correctionEnabled"] = true;
-
- valid = true;
-}
-
-void QMaliitPlatformInputContextPrivate::sendStateUpdate(bool focusChanged)
-{
- server->updateWidgetInformation(imState, focusChanged);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.h b/src/plugins/platforminputcontexts/maliit/serveraddressproxy.h
deleted file mode 100644
index a9c31de4af..0000000000
--- a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SERVERADDRESSPROXY_H
-#define SERVERADDRESSPROXY_H
-
-#include <QtCore/QObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-#include <QtDBus/QtDBus>
-
-/*
- * Proxy class for interface org.maliit.Server.Address
- */
-class OrgMaliitServerAddressInterface: public QDBusAbstractInterface
-{
- Q_OBJECT
-public:
- static inline const char *staticInterfaceName()
- { return "org.maliit.Server.Address"; }
-
-public:
- OrgMaliitServerAddressInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
-
- ~OrgMaliitServerAddressInterface();
-
- Q_PROPERTY(QString address READ address)
- inline QString address() const
- { return qvariant_cast< QString >(property("address")); }
-
-public Q_SLOTS: // METHODS
-Q_SIGNALS: // SIGNALS
-};
-
-namespace org {
- namespace maliit {
- namespace Server {
- typedef ::OrgMaliitServerAddressInterface Address;
- }
- }
-}
-#endif
diff --git a/src/plugins/platforminputcontexts/maliit/serverproxy.h b/src/plugins/platforminputcontexts/maliit/serverproxy.h
deleted file mode 100644
index e32adfdd94..0000000000
--- a/src/plugins/platforminputcontexts/maliit/serverproxy.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SERVER_H_1318935108
-#define SERVER_H_1318935108
-
-#include <QtCore/QObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-#include <QtDBus/QtDBus>
-
-/*
- * Proxy class for interface com.meego.inputmethod.uiserver1
- */
-class ComMeegoInputmethodUiserver1Interface: public QDBusAbstractInterface
-{
- Q_OBJECT
-public:
- static inline const char *staticInterfaceName()
- { return "com.meego.inputmethod.uiserver1"; }
-
-public:
- ComMeegoInputmethodUiserver1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
-
- ~ComMeegoInputmethodUiserver1Interface();
-
-public Q_SLOTS: // METHODS
- inline QDBusPendingReply<> activateContext()
- {
- QList<QVariant> argumentList;
- return asyncCallWithArgumentList(QLatin1String("activateContext"), argumentList);
- }
-
- inline QDBusPendingReply<> appOrientationAboutToChange(int in0)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(in0);
- return asyncCallWithArgumentList(QLatin1String("appOrientationAboutToChange"), argumentList);
- }
-
- inline QDBusPendingReply<> appOrientationChanged(int in0)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(in0);
- return asyncCallWithArgumentList(QLatin1String("appOrientationChanged"), argumentList);
- }
-
- inline QDBusPendingReply<> hideInputMethod()
- {
- QList<QVariant> argumentList;
- return asyncCallWithArgumentList(QLatin1String("hideInputMethod"), argumentList);
- }
-
- inline QDBusPendingReply<> mouseClickedOnPreedit(int in0, int in1, int in2, int in3, int in4, int in5)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3) << QVariant::fromValue(in4) << QVariant::fromValue(in5);
- return asyncCallWithArgumentList(QLatin1String("mouseClickedOnPreedit"), argumentList);
- }
-
- inline QDBusPendingReply<> processKeyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uint in6, uint in7, uint in8)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3) << QVariant::fromValue(in4) << QVariant::fromValue(in5) << QVariant::fromValue(in6) << QVariant::fromValue(in7) << QVariant::fromValue(in8);
- return asyncCallWithArgumentList(QLatin1String("processKeyEvent"), argumentList);
- }
-
- inline QDBusPendingReply<> setPreedit(const QString &in0, int in1)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
- return asyncCallWithArgumentList(QLatin1String("setPreedit"), argumentList);
- }
-
- inline QDBusPendingReply<> showInputMethod()
- {
- QList<QVariant> argumentList;
- return asyncCallWithArgumentList(QLatin1String("showInputMethod"), argumentList);
- }
-
- inline QDBusPendingReply<> updateWidgetInformation(const QMap<QString, QVariant> &stateInformation, bool focusChanged)
- {
- QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), "updateWidgetInformation");
-
- QDBusArgument map;
- map.beginMap(QVariant::String, qMetaTypeId<QDBusVariant>());
- for (QMap<QString, QVariant>::ConstIterator it = stateInformation.constBegin(), end = stateInformation.constEnd();
- it != end; ++it) {
- map.beginMapEntry();
- map << it.key();
- map << QDBusVariant(it.value());
- map.endMapEntry();
- }
- map.endMap();
-
- QList<QVariant> args;
- args << QVariant::fromValue(map) << QVariant(focusChanged);
- msg.setArguments(args);
- return connection().asyncCall(msg);
- }
-
- inline QDBusPendingReply<> reset()
- {
- return asyncCall(QLatin1String("reset"));
- }
-
- inline QDBusPendingReply<> setCopyPasteState(bool in0, bool in1)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
- return asyncCallWithArgumentList(QLatin1String("setCopyPasteState"), argumentList);
- }
-
-Q_SIGNALS: // SIGNALS
-};
-
-namespace com {
- namespace meego {
- namespace inputmethod {
- typedef ::ComMeegoInputmethodUiserver1Interface uiserver1;
- }
- }
-}
-#endif
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
index 733b70be58..60b66bfb35 100644
--- a/src/plugins/platforminputcontexts/platforminputcontexts.pro
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -1,7 +1,7 @@
TEMPLATE = subdirs
qtHaveModule(dbus) {
-!mac:!win32:SUBDIRS += ibus maliit
+!mac:!win32:SUBDIRS += ibus
}
unix:!macx:!contains(DEFINES, QT_NO_XKBCOMMON): {
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
new file mode 100644
index 0000000000..07f3371e72
--- /dev/null
+++ b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidjniaccessibility.h"
+#include "androidjnimain.h"
+#include "qandroidplatformintegration.h"
+#include "qpa/qplatformaccessibility.h"
+#include "qguiapplication.h"
+#include "qwindow.h"
+#include "qrect.h"
+#include "private/qaccessible2_p.h"
+
+#include "qdebug.h"
+
+static const char m_qtTag[] = "QtA11y";
+static const char m_classErrorMsg[] = "Can't find class \"%s\"";
+static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
+
+namespace QtAndroidAccessibility
+{
+ static void setActive(JNIEnv */*env*/, jobject /*thiz*/, jboolean active)
+ {
+ QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration();
+ if (platformIntegration)
+ platformIntegration->accessibility()->setActive(active);
+ else
+ __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Could not activate platform accessibility.");
+ }
+
+ QAccessibleInterface *interfaceFromId(jint objectId)
+ {
+ QAccessibleInterface *iface = 0;
+ if (objectId == -1) {
+ QWindow *win = qApp->focusWindow();
+ if (win)
+ iface = win->accessibleRoot();
+ } else {
+ iface = QAccessible::accessibleInterface(objectId);
+ }
+ return iface;
+ }
+
+ static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
+ {
+ QAccessibleInterface *iface = interfaceFromId(objectId);
+ if (iface) {
+ jintArray jArray = env->NewIntArray(jsize(iface->childCount()));
+ for (int i = 0; i < iface->childCount(); ++i) {
+ QAccessibleInterface *child = iface->child(i);
+ if (child) {
+ QAccessible::Id ifaceId = QAccessible::uniqueId(child);
+ jint jid = ifaceId;
+ env->SetIntArrayRegion(jArray, i, 1, &jid);
+ }
+ }
+ return jArray;
+ }
+
+ return env->NewIntArray(jsize(0));
+ }
+
+ static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
+ {
+ QAccessibleInterface *iface = interfaceFromId(objectId);
+ if (iface) {
+ QAccessibleInterface *parent = iface->parent();
+ if (parent) {
+ if (parent->role() == QAccessible::Application)
+ return -1;
+ return QAccessible::uniqueId(parent);
+ }
+ }
+ return -1;
+ }
+
+ static jobject screenRect(JNIEnv *env, jobject /*thiz*/, jint objectId)
+ {
+ QRect rect;
+ QAccessibleInterface *iface = interfaceFromId(objectId);
+ if (iface && iface->isValid()) {
+ rect = iface->rect();
+ }
+
+ jclass rectClass = env->FindClass("android/graphics/Rect");
+ jmethodID ctor = env->GetMethodID(rectClass, "<init>", "(IIII)V");
+ jobject jrect = env->NewObject(rectClass, ctor, rect.left(), rect.top(), rect.right(), rect.bottom());
+ return jrect;
+ }
+
+ static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y)
+ {
+ QAccessibleInterface *root = interfaceFromId(-1);
+ if (root) {
+ QAccessibleInterface *child = root->childAt((int)x, (int)y);
+ QAccessibleInterface *lastChild = 0;
+ while (child && (child != lastChild)) {
+ lastChild = child;
+ child = child->childAt((int)x, (int)y);
+ }
+ if (lastChild)
+ return QAccessible::uniqueId(lastChild);
+ }
+ return -1;
+ }
+
+ static jboolean clickAction(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
+ {
+// qDebug() << "A11Y: CLICK: " << objectId;
+ QAccessibleInterface *iface = interfaceFromId(objectId);
+ if (iface && iface->actionInterface()) {
+ if (iface->actionInterface()->actionNames().contains(QAccessibleActionInterface::pressAction()))
+ iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction());
+ else
+ iface->actionInterface()->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ return false;
+ }
+
+
+#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
+clazz = env->FindClass(CLASS_NAME); \
+if (!clazz) { \
+ __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_classErrorMsg, CLASS_NAME); \
+ return JNI_FALSE; \
+}
+
+ //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE);
+
+#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, VALUE) \
+{ \
+ jclass clazz = env->GetObjectClass(OBJECT); \
+ jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!method) { \
+ __android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
+ return; \
+ } \
+ env->CallVoidMethod(OBJECT, method, VALUE); \
+}
+
+
+ static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
+ {
+ QString desc;
+ QAccessibleInterface *iface = interfaceFromId(objectId);
+ if (iface && iface->isValid()) {
+ desc = iface->text(QAccessible::Name);
+ if (desc.isEmpty())
+ desc = iface->text(QAccessible::Description);
+
+ desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
+ }
+
+ jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
+ return jdesc;
+ }
+
+ static void populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node)
+ {
+ QAccessibleInterface *iface = interfaceFromId(objectId);
+ if (!iface || !iface->isValid()) {
+ __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Accessibility: populateNode for Invalid ID");
+ return;
+ }
+ QAccessible::State state = iface->state();
+
+ QString desc = iface->text(QAccessible::Name);
+ if (desc.isEmpty())
+ desc = iface->text(QAccessible::Description);
+ if ((iface->role() != QAccessible::NoRole) &&
+ (iface->role() != QAccessible::Client) &&
+ (iface->role() != QAccessible::Pane)) {
+ desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
+ }
+
+ CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled)
+ //CALL_METHOD(node, "setFocusable", "(Z)V", state.focusable)
+ CALL_METHOD(node, "setFocusable", "(Z)V", true)
+ //CALL_METHOD(node, "setFocused", "(Z)V", state.focused)
+ CALL_METHOD(node, "setCheckable", "(Z)V", state.checkable)
+ CALL_METHOD(node, "setChecked", "(Z)V", state.checked)
+ CALL_METHOD(node, "setVisibleToUser", "(Z)V", !state.invisible)
+
+ if (iface->actionInterface()) {
+ QStringList actions = iface->actionInterface()->actionNames();
+ bool clickable = actions.contains(QAccessibleActionInterface::pressAction());
+ bool toggle = actions.contains(QAccessibleActionInterface::toggleAction());
+ if (clickable || toggle) {
+ CALL_METHOD(node, "setClickable", "(Z)V", clickable)
+ CALL_METHOD(node, "addAction", "(I)V", 16) // ACTION_CLICK defined in AccessibilityNodeInfo
+ }
+ }
+
+ jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
+ //CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc)
+ CALL_METHOD(node, "setContentDescription", "(Ljava/lang/CharSequence;)V", jdesc)
+ }
+
+ static JNINativeMethod methods[] = {
+ {"setActive","(Z)V",(void*)setActive},
+ {"childIdListForAccessibleObject", "(I)[I", (jintArray)childIdListForAccessibleObject},
+ {"parentId", "(I)I", (void*)parentId},
+ {"descriptionForAccessibleObject", "(I)Ljava/lang/String;", (jstring)descriptionForAccessibleObject},
+ {"screenRect", "(I)Landroid/graphics/Rect;", (jobject)screenRect},
+ {"hitTest", "(FF)I", (void*)hitTest},
+ {"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)V", (void*)populateNode},
+ {"clickAction", "(I)Z", (void*)clickAction},
+ };
+
+ bool registerNatives(JNIEnv *env)
+ {
+ jclass clazz;
+ FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/accessibility/QtNativeAccessibility");
+ jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+
+ if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/src/plugins/platforms/kms/qkmsudevhandler.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.h
index e32723e78f..e708138c33 100644
--- a/src/plugins/platforms/kms/qkmsudevhandler.cpp
+++ b/src/plugins/platforms/android/src/androidjniaccessibility.h
@@ -39,17 +39,13 @@
**
****************************************************************************/
-#include <qkmsudevhandler.h>
+#ifndef ANDROIDJNIACCESSIBILITY_H
+#define ANDROIDJNIACCESSIBILITY_H
+#include <jni.h>
-QT_BEGIN_NAMESPACE
-
-QKmsUdevHandler::QKmsUdevHandler(QObject *parent)
- : QObject(parent)
-{
-}
-
-QKmsUdevHandler::~QKmsUdevHandler()
+namespace QtAndroidAccessibility
{
+ bool registerNatives(JNIEnv *env);
}
-QT_END_NAMESPACE
+#endif // ANDROIDJNIINPUT_H
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp
index 75cb617ca8..b31e74bb52 100644
--- a/src/plugins/platforms/android/src/androidjniinput.cpp
+++ b/src/plugins/platforms/android/src/androidjniinput.cpp
@@ -411,6 +411,24 @@ namespace QtAndroidInput
case 0x00000018:
return Qt::Key_VolumeUp;
+ case 0x000000b7: // KEYCODE_PROG_RED
+ return Qt::Key_Red;
+
+ case 0x000000b8: // KEYCODE_PROG_GREEN
+ return Qt::Key_Green;
+
+ case 0x000000b9: // KEYCODE_PROG_YELLOW
+ return Qt::Key_Yellow;
+
+ case 0x000000ba: // KEYCODE_PROG_BLUE
+ return Qt::Key_Blue;
+
+ case 0x000000a6: // KEYCODE_CHANNEL_UP
+ return Qt::Key_ChannelUp;
+
+ case 0x000000a7: // KEYCODE_CHANNEL_DOWN
+ return Qt::Key_ChannelDown;
+
case 0x00000000: // KEYCODE_UNKNOWN
case 0x00000011: // KEYCODE_STAR ?!?!?
case 0x00000012: // KEYCODE_POUND ?!?!?
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
index 74183b3107..b426839f3d 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -55,6 +55,7 @@
#include <stdlib.h>
#include "androidjnimain.h"
+#include "androidjniaccessibility.h"
#include "androidjniinput.h"
#include "androidjniclipboard.h"
#include "androidjnimenu.h"
@@ -88,6 +89,9 @@ static AAssetManager *m_assetManager = NULL;
static jobject m_resourcesObj;
static jobject m_activityObject = NULL;
+static bool m_activityActive = true; // defaults to true because when the platform plugin is
+ // initialized, QtActivity::onResume() has already been called
+
static jclass m_bitmapClass = 0;
static jmethodID m_createBitmapMethodID = 0;
static jobject m_ARGB_8888_BitmapConfigValue = 0;
@@ -319,6 +323,12 @@ namespace QtAndroid
return m_activityObject;
}
+ void setApplicationActive()
+ {
+ if (m_activityActive)
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
+ }
+
jobject createBitmap(QImage img, JNIEnv *env)
{
if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16)
@@ -655,6 +665,16 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
#endif
}
+static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
+{
+ m_activityActive = (state == Qt::ApplicationActive);
+
+ if (!m_androidPlatformIntegration)
+ return;
+
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state));
+}
+
static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation)
{
if (m_androidPlatformIntegration == 0)
@@ -681,6 +701,7 @@ static JNINativeMethod methods[] = {
{"lockSurface", "()V", (void *)lockSurface},
{"unlockSurface", "()V", (void *)unlockSurface},
{"updateWindow", "()V", (void *)updateWindow},
+ {"updateApplicationState", "(I)V", (void *)updateApplicationState},
{"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged}
};
@@ -797,7 +818,8 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
if (!registerNatives(env)
|| !QtAndroidInput::registerNatives(env)
|| !QtAndroidClipboard::registerNatives(env)
- || !QtAndroidMenu::registerNatives(env)) {
+ || !QtAndroidMenu::registerNatives(env)
+ || !QtAndroidAccessibility::registerNatives(env)) {
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
}
diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h
index f75df55e02..9a3d8a9607 100644
--- a/src/plugins/platforms/android/src/androidjnimain.h
+++ b/src/plugins/platforms/android/src/androidjnimain.h
@@ -88,6 +88,8 @@ namespace QtAndroid
jclass applicationClass();
jobject activity();
+ void setApplicationActive();
+
jobject createBitmap(QImage img, JNIEnv *env = 0);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
diff --git a/src/plugins/platforms/android/src/androidplatformplugin.cpp b/src/plugins/platforms/android/src/androidplatformplugin.cpp
index 71c5096e16..79e23c2d32 100644
--- a/src/plugins/platforms/android/src/androidplatformplugin.cpp
+++ b/src/plugins/platforms/android/src/androidplatformplugin.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QAndroidPlatformIntegrationPlugin: public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "android.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "android.json")
public:
QPlatformIntegration *create(const QString &key, const QStringList &paramList);
};
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
index 2eac8d248c..4934047af9 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
@@ -135,6 +135,12 @@ void QAndroidOpenGLPlatformWindow::raise()
void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
{
QEglFSWindow::setVisible(visible);
+
+ // The Android Activity is activated before Qt is initialized, causing the application state to
+ // never be set to 'active'. We explicitly set this state when the first window becomes visible.
+ if (visible)
+ QtAndroid::setApplicationActive();
+
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
QWindowSystemInterface::flushWindowSystemEvents();
}
diff --git a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.cpp b/src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp
index 6ff508d66c..229368345b 100644
--- a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,18 +39,20 @@
**
****************************************************************************/
-#include "serveraddressproxy.h"
-/*
- * Implementation of interface class OrgMaliitServerAddressInterface
- */
+#include "qandroidplatformaccessibility.h"
-OrgMaliitServerAddressInterface::OrgMaliitServerAddressInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
- : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
-{
-}
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformAccessibility::QAndroidPlatformAccessibility()
+{}
+
+QAndroidPlatformAccessibility::~QAndroidPlatformAccessibility()
+{}
-OrgMaliitServerAddressInterface::~OrgMaliitServerAddressInterface()
+void QAndroidPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent */*event*/)
{
+ // FIXME send events
}
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsudevdrmhandler.h b/src/plugins/platforms/android/src/qandroidplatformaccessibility.h
index 4ceecb11a8..1b87f11919 100644
--- a/src/plugins/platforms/kms/qkmsudevdrmhandler.h
+++ b/src/plugins/platforms/android/src/qandroidplatformaccessibility.h
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,28 +39,23 @@
**
****************************************************************************/
-#ifndef QKMSUDEVDRMHANDLER_H
-#define QKMSUDEVDRMHANDLER_H
-#include <QObject>
+#ifndef QANDROIDPLATFORMACCESSIBILITY_H
+#define QANDROIDPLATFORMACCESSIBILITY_H
-#include <qkmsudevhandler.h>
+#include <qpa/qplatformaccessibility.h>
QT_BEGIN_NAMESPACE
-class QKmsIntegration;
-
-class QKmsUdevDRMHandler : public QKmsUdevHandler
+class QAndroidPlatformAccessibility: public QPlatformAccessibility
{
public:
- QKmsUdevDRMHandler(QKmsIntegration *integration);
-
- QObject *create(struct udev_device *device);
+ QAndroidPlatformAccessibility();
+ ~QAndroidPlatformAccessibility();
-private:
- QKmsIntegration *m_integration;
+ virtual void notifyAccessibilityUpdate(QAccessibleEvent *event);
};
QT_END_NAMESPACE
-#endif // QKMSUDEVDRMHANDLER_H
+#endif
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
index 636a2b3853..286d4cc7f2 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
@@ -50,6 +50,7 @@
#include "qandroidplatformservices.h"
#include "qandroidplatformfontdatabase.h"
#include "qandroidplatformclipboard.h"
+#include "qandroidplatformaccessibility.h"
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#ifndef ANDROID_PLUGIN_OPENGL
@@ -66,6 +67,7 @@
#endif
#include "qandroidplatformtheme.h"
+#include "qandroidsystemlocale.h"
QT_BEGIN_NAMESPACE
@@ -86,6 +88,9 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &paramList)
: m_touchDevice(0)
+#ifndef QT_NO_ACCESSIBILITY
+ , m_accessibility(0)
+#endif
{
Q_UNUSED(paramList);
@@ -108,13 +113,17 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_androidFDB = new QAndroidPlatformFontDatabase();
m_androidPlatformServices = new QAndroidPlatformServices();
m_androidPlatformClipboard = new QAndroidPlatformClipboard();
+
+ m_androidSystemLocale = new QAndroidSystemLocale;
}
bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case ApplicationState: return true;
case NonFullScreenWindows: return false;
+ case NativeWidgets: return false;
default:
#ifndef ANDROID_PLUGIN_OPENGL
return QPlatformIntegration::hasCapability(cap);
@@ -184,6 +193,7 @@ QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
{
delete m_androidPlatformNativeInterface;
delete m_androidFDB;
+ delete m_androidSystemLocale;
QtAndroid::setAndroidPlatformIntegration(NULL);
}
QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const
@@ -255,6 +265,15 @@ void QAndroidPlatformIntegration::setDefaultDesktopSize(int gw, int gh)
m_defaultGeometryHeight = gh;
}
+#ifndef QT_NO_ACCESSIBILITY
+QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const
+{
+ if (!m_accessibility)
+ m_accessibility = new QAndroidPlatformAccessibility();
+ return m_accessibility;
+}
+#endif
+
#ifndef ANDROID_PLUGIN_OPENGL
void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h
index 6cc191701d..83d7028665 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
class QDesktopWidget;
class QAndroidPlatformServices;
+class QAndroidSystemLocale;
+class QPlatformAccessibility;
#ifdef ANDROID_PLUGIN_OPENGL
class QAndroidOpenGLPlatformWindow;
@@ -112,6 +114,10 @@ public:
QPlatformNativeInterface *nativeInterface() const;
QPlatformServices *services() const;
+#ifndef QT_NO_ACCESSIBILITY
+ virtual QPlatformAccessibility *accessibility() const;
+#endif
+
QVariant styleHint(StyleHint hint) const;
QStringList themeNames() const;
@@ -154,6 +160,10 @@ private:
QAndroidPlatformNativeInterface *m_androidPlatformNativeInterface;
QAndroidPlatformServices *m_androidPlatformServices;
QPlatformClipboard *m_androidPlatformClipboard;
+ QAndroidSystemLocale *m_androidSystemLocale;
+#ifndef QT_NO_ACCESSIBILITY
+ mutable QPlatformAccessibility *m_accessibility;
+#endif
mutable QAndroidInputContext m_platformInputContext;
};
diff --git a/src/plugins/platforms/android/src/qandroidsystemlocale.cpp b/src/plugins/platforms/android/src/qandroidsystemlocale.cpp
new file mode 100644
index 0000000000..24ae503335
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidsystemlocale.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidsystemlocale.h"
+#include "androidjnimain.h"
+#include "private/qjniobject_p.h"
+#include "private/qjnihelpers_p.h"
+#include "qdatetime.h"
+#include "qstringlist.h"
+#include "qvariant.h"
+
+QT_BEGIN_NAMESPACE
+
+QAndroidSystemLocale::QAndroidSystemLocale() : m_locale(QLocale::C)
+{
+}
+
+void QAndroidSystemLocale::getLocaleFromJava() const
+{
+ QWriteLocker locker(&m_lock);
+
+ QJNILocalRef<jobject> javaLocaleRef;
+ QJNIObject javaActivity(QtAndroid::activity());
+ if (javaActivity.isValid()) {
+ QJNIObject resources(javaActivity.callObjectMethod<jobject>("getResources", "()Landroid/content/res/Resources;").object());
+ QJNIObject configuration(resources.callObjectMethod<jobject>("getConfiguration", "()Landroid/content/res/Configuration;").object());
+
+ javaLocaleRef = configuration.getObjectField<jobject>("locale", "Ljava/util/Locale;");
+ } else {
+ javaLocaleRef = QJNIObject::callStaticObjectMethod<jobject>("java/util/Locale", "getDefault", "()Ljava/util/Locale;");
+ }
+
+ QJNIObject javaLocaleObject(javaLocaleRef.object());
+ QString languageCode = qt_convertJString(javaLocaleObject.callObjectMethod<jstring>("getLanguage", "()Ljava/lang/String;").object());
+ QString countryCode = qt_convertJString(javaLocaleObject.callObjectMethod<jstring>("getCountry", "()Ljava/lang/String;").object());
+
+ m_locale = QLocale(languageCode + QLatin1Char('_') + countryCode);
+}
+
+QVariant QAndroidSystemLocale::query(QueryType type, QVariant in) const
+{
+ if (type == LocaleChanged) {
+ getLocaleFromJava();
+ return QVariant();
+ }
+
+ QReadLocker locker(&m_lock);
+
+ switch (type) {
+ case DecimalPoint:
+ return m_locale.decimalPoint();
+ case GroupSeparator:
+ return m_locale.groupSeparator();
+ case ZeroDigit:
+ return m_locale.zeroDigit();
+ case NegativeSign:
+ return m_locale.negativeSign();
+ case DateFormatLong:
+ return m_locale.dateFormat(QLocale::LongFormat);
+ case DateFormatShort:
+ return m_locale.dateFormat(QLocale::ShortFormat);
+ case TimeFormatLong:
+ return m_locale.timeFormat(QLocale::LongFormat);
+ case TimeFormatShort:
+ return m_locale.timeFormat(QLocale::ShortFormat);
+ case DayNameLong:
+ return m_locale.dayName(in.toInt(), QLocale::LongFormat);
+ case DayNameShort:
+ return m_locale.dayName(in.toInt(), QLocale::ShortFormat);
+ case MonthNameLong:
+ return m_locale.monthName(in.toInt(), QLocale::LongFormat);
+ case MonthNameShort:
+ return m_locale.monthName(in.toInt(), QLocale::ShortFormat);
+ case StandaloneMonthNameLong:
+ return m_locale.standaloneMonthName(in.toInt(), QLocale::LongFormat);
+ case StandaloneMonthNameShort:
+ return m_locale.standaloneMonthName(in.toInt(), QLocale::ShortFormat);
+ case DateToStringLong:
+ return m_locale.toString(in.toDate(), QLocale::LongFormat);
+ case DateToStringShort:
+ return m_locale.toString(in.toDate(), QLocale::ShortFormat);
+ case TimeToStringLong:
+ return m_locale.toString(in.toTime(), QLocale::LongFormat);
+ case TimeToStringShort:
+ return m_locale.toString(in.toTime(), QLocale::ShortFormat);
+ case DateTimeFormatLong:
+ return m_locale.dateTimeFormat(QLocale::LongFormat);
+ case DateTimeFormatShort:
+ return m_locale.dateTimeFormat(QLocale::ShortFormat);
+ case DateTimeToStringLong:
+ return m_locale.toString(in.toDateTime(), QLocale::LongFormat);
+ case DateTimeToStringShort:
+ return m_locale.toString(in.toDateTime(), QLocale::ShortFormat);
+ case PositiveSign:
+ return m_locale.positiveSign();
+ case AMText:
+ return m_locale.amText();
+ case PMText:
+ return m_locale.pmText();
+ case FirstDayOfWeek:
+ return m_locale.firstDayOfWeek();
+ case CurrencySymbol:
+ return m_locale .currencySymbol(QLocale::CurrencySymbolFormat(in.toUInt()));
+ case CurrencyToString: {
+ switch (in.type()) {
+ case QVariant::Int:
+ return m_locale .toCurrencyString(in.toInt());
+ case QVariant::UInt:
+ return m_locale .toCurrencyString(in.toUInt());
+ case QVariant::Double:
+ return m_locale .toCurrencyString(in.toDouble());
+ case QVariant::LongLong:
+ return m_locale .toCurrencyString(in.toLongLong());
+ case QVariant::ULongLong:
+ return m_locale .toCurrencyString(in.toULongLong());
+ default:
+ break;
+ }
+ return QString();
+ }
+ case StringToStandardQuotation:
+ return m_locale.quoteString(in.value<QStringRef>());
+ case StringToAlternateQuotation:
+ return m_locale.quoteString(in.value<QStringRef>(), QLocale::AlternateQuotation);
+ case ListToSeparatedString:
+ return m_locale.createSeparatedList(in.value<QStringList>());
+ case LocaleChanged:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This can't happen.");
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QLocale QAndroidSystemLocale::fallbackUiLocale() const
+{
+ QReadLocker locker(&m_lock);
+ return m_locale;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/qandroidsystemlocale.h b/src/plugins/platforms/android/src/qandroidsystemlocale.h
new file mode 100644
index 0000000000..fc2f6fad98
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidsystemlocale.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDSYSTEMLOCALE_H
+#define QANDROIDSYSTEMLOCALE_H
+
+#include "private/qlocale_p.h"
+#include <QtCore/qreadwritelock.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidSystemLocale : public QSystemLocale
+{
+public:
+ QAndroidSystemLocale();
+
+ virtual QVariant query(QueryType type, QVariant in) const;
+ virtual QLocale fallbackUiLocale() const;
+
+private:
+ void getLocaleFromJava() const;
+
+ mutable QLocale m_locale;
+ mutable QReadWriteLock m_lock;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDSYSTEMLOCALE_H
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
index 94a69c10c7..f5fce0ae34 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
@@ -41,6 +41,9 @@
#include "qandroidplatformwindow.h"
+#include "androidjnimain.h"
+#include <qpa/qwindowsysteminterface.h>
+
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window)
{
}
@@ -54,3 +57,13 @@ void QAndroidPlatformWindow::propagateSizeHints()
{
//shut up warning from default implementation
}
+
+void QAndroidPlatformWindow::setVisible(bool visible)
+{
+ QFbWindow::setVisible(visible);
+
+ // The Android Activity is activated before Qt is initialized, causing the application state to
+ // never be set to 'active'. We explicitly set this state when the first window becomes visible.
+ if (visible)
+ QtAndroid::setApplicationActive();
+}
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
index 3ee815fd69..58e6451ea1 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
@@ -52,6 +52,8 @@ public:
void propagateSizeHints();
+ void setVisible(bool visible);
+
public slots:
void setGeometry(const QRect &rect);
diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri
index 76539b50ab..6cc41c3e68 100644
--- a/src/plugins/platforms/android/src/src.pri
+++ b/src/plugins/platforms/android/src/src.pri
@@ -11,6 +11,7 @@ INCLUDEPATH += $$PWD/../../../../3rdparty/android/src
SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/androidjnimain.cpp \
+ $$PWD/androidjniaccessibility.cpp \
$$PWD/androidjniinput.cpp \
$$PWD/androidjnimenu.cpp \
$$PWD/androidjniclipboard.cpp \
@@ -18,28 +19,33 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/qandroidplatformservices.cpp \
$$PWD/qandroidassetsfileenginehandler.cpp \
$$PWD/qandroidinputcontext.cpp \
+ $$PWD/qandroidplatformaccessibility.cpp \
$$PWD/qandroidplatformfontdatabase.cpp \
$$PWD/qandroidplatformclipboard.cpp \
$$PWD/qandroidplatformtheme.cpp \
$$PWD/qandroidplatformmenubar.cpp \
$$PWD/qandroidplatformmenu.cpp \
- $$PWD/qandroidplatformmenuitem.cpp
+ $$PWD/qandroidplatformmenuitem.cpp \
+ $$PWD/qandroidsystemlocale.cpp
HEADERS += $$PWD/qandroidplatformintegration.h \
$$PWD/androidjnimain.h \
+ $$PWD/androidjniaccessibility.h \
$$PWD/androidjniinput.h \
$$PWD/androidjnimenu.h \
$$PWD/androidjniclipboard.h \
$$PWD/qandroidplatformservices.h \
$$PWD/qandroidassetsfileenginehandler.h \
$$PWD/qandroidinputcontext.h \
+ $$PWD/qandroidplatformaccessibility.h \
$$PWD/qandroidplatformfontdatabase.h \
$$PWD/qandroidplatformclipboard.h \
$$PWD/qandroidplatformtheme.h \
$$PWD/qandroidplatformmenubar.h \
$$PWD/qandroidplatformmenu.h \
- $$PWD/qandroidplatformmenuitem.h
+ $$PWD/qandroidplatformmenuitem.h \
+ $$PWD/qandroidsystemlocale.h
#Non-standard install directory, QTBUG-29859
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
index 6adcb27817..b730514b12 100644
--- a/src/plugins/platforms/cocoa/main.mm
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
class QCocoaIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "cocoa.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "cocoa.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
index 2376b35501..ffb12ea846 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -89,8 +89,10 @@
Cocoa Application Categories
*/
#include "qglobal.h"
+#include "private/qcore_mac_p.h"
#import <AppKit/AppKit.h>
+
@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
@interface NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
@@ -106,6 +108,8 @@
}
@end
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSApplication);
+
QT_BEGIN_NAMESPACE
void qt_redirectNSApplicationSendEvent();
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
index d962ef8f75..c293f4cd52 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -87,12 +87,12 @@ QT_USE_NAMESPACE
- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu
{
- [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] setDockMenu:newMenu];
+ [[QCocoaApplicationDelegate sharedDelegate] setDockMenu:newMenu];
}
- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)
{
- return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader];
+ return [[QCocoaApplicationDelegate sharedDelegate] menuLoader];
}
- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel
@@ -155,7 +155,7 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
@end
-@implementation QT_MANGLE_NAMESPACE(QNSApplication)
+@implementation QNSApplication
- (void)qt_sendEvent_original:(NSEvent *)event
{
@@ -189,7 +189,7 @@ QT_BEGIN_NAMESPACE
void qt_redirectNSApplicationSendEvent()
{
- if ([NSApp isMemberOfClass:[QT_MANGLE_NAMESPACE(QNSApplication) class]]) {
+ if ([NSApp isMemberOfClass:[QNSApplication class]]) {
// No need to change implementation since Qt
// already controls a subclass of NSApplication
return;
@@ -202,7 +202,7 @@ void qt_redirectNSApplicationSendEvent()
qt_cocoa_change_implementation(
[NSApplication class],
@selector(sendEvent:),
- [QT_MANGLE_NAMESPACE(QNSApplication) class],
+ [QNSApplication class],
@selector(qt_sendEvent_replacement:),
@selector(qt_sendEvent_original:));
}
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
index e44b2d1b6d..7f6c4224df 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -90,6 +90,7 @@
#import <Cocoa/Cocoa.h>
#include <qglobal.h>
+#include <private/qcore_mac_p.h>
@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
@@ -108,3 +109,5 @@
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
- (void) removeAppleEventHandlers;
@end
+
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate);
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 3ec6ad7a20..423d552627 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -88,14 +88,14 @@
QT_USE_NAMESPACE
-static QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *sharedCocoaApplicationDelegate = nil;
+static QCocoaApplicationDelegate *sharedCocoaApplicationDelegate = nil;
static void cleanupCocoaApplicationDelegate()
{
[sharedCocoaApplicationDelegate release];
}
-@implementation QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)
+@implementation QCocoaApplicationDelegate
- (id)init
{
@@ -144,7 +144,7 @@ static void cleanupCocoaApplicationDelegate()
return nil;
}
-+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate
++ (QCocoaApplicationDelegate *)sharedDelegate
{
@synchronized(self) {
if (sharedCocoaApplicationDelegate == nil)
@@ -166,14 +166,14 @@ static void cleanupCocoaApplicationDelegate()
return [[dockMenu retain] autorelease];
}
-- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+- (void)setMenuLoader:(QCocoaMenuLoader *)menuLoader
{
[menuLoader retain];
[qtMenuLoader release];
qtMenuLoader = menuLoader;
}
-- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+- (QCocoaMenuLoader *)menuLoader
{
return [[qtMenuLoader retain] autorelease];
}
@@ -183,7 +183,7 @@ static void cleanupCocoaApplicationDelegate()
[[NSApp mainMenu] cancelTracking];
bool handle_quit = true;
- NSMenuItem *quitMenuItem = [[[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader] quitMenuItem];
+ NSMenuItem *quitMenuItem = [[[QCocoaApplicationDelegate sharedDelegate] menuLoader] quitMenuItem];
if (!QGuiApplicationPrivate::instance()->modalWindowList.isEmpty()
&& [quitMenuItem isEnabled]) {
int visible = 0;
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index 3379a26650..d90d77ec1d 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -87,7 +87,9 @@ static NSButton *macCreateButton(const char *text, NSView *superview)
- (void)finishOffWithCode:(NSInteger)code;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSColorPanelDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
+
+@implementation QNSColorPanelDelegate
- (id)init
{
@@ -308,12 +310,13 @@ static NSButton *macCreateButton(const char *text, NSView *superview)
// close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
[NSApp runModalForWindow:mColorPanel];
+ mDialogIsExecuting = false;
return (mResultCode == NSOKButton);
}
-- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode
+- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mResultCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected);
+ return (mResultCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (BOOL)windowShouldClose:(id)window
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h
index 701e8e2dbf..8a8b1d946c 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h
@@ -62,10 +62,10 @@ public:
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
void hide();
- void setDirectory(const QString &directory);
- QString directory() const;
- void selectFile(const QString &filename);
- QStringList selectedFiles() const;
+ void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ QUrl directory() const Q_DECL_OVERRIDE;
+ void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
+ QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
void setFilter();
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 76cd235514..b3bc4a8ebf 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -139,7 +139,9 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
+
+@implementation QNSOpenSavePanelDelegate
- (id)initWithAcceptMode:
(const QString &)selectFile
@@ -148,7 +150,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
{
self = [super init];
mOptions = options;
- if (mOptions->acceptMode() == QT_PREPEND_NAMESPACE(QFileDialogOptions::AcceptOpen)){
+ if (mOptions->acceptMode() == QFileDialogOptions::AcceptOpen){
mOpenPanel = [NSOpenPanel openPanel];
mSavePanel = mOpenPanel;
} else {
@@ -234,7 +236,7 @@ static QString strippedText(QString s)
- (void)closePanel
{
- *mCurrentSelection = QT_PREPEND_NAMESPACE(QCFString::toQString)([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
+ *mCurrentSelection = QCFString::toQString([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
if ([mSavePanel respondsToSelector:@selector(close)])
[mSavePanel close];
if ([mSavePanel isSheet])
@@ -245,7 +247,7 @@ static QString strippedText(QString s)
{
if (mOpenPanel){
QFileInfo info(*mCurrentSelection);
- NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath());
+ NSString *filepath = QCFString::toNSString(info.filePath());
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
@@ -264,12 +266,12 @@ static QString strippedText(QString s)
- (BOOL)runApplicationModalPanel
{
QFileInfo info(*mCurrentSelection);
- NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath());
+ NSString *filepath = QCFString::toNSString(info.filePath());
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
- [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
+ [mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""];
// Call processEvents in case the event dispatcher has been interrupted, and needs to do
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
@@ -281,22 +283,22 @@ static QString strippedText(QString s)
return (mReturnCode == NSOKButton);
}
-- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode
+- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mReturnCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected);
+ return (mReturnCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (void)showWindowModalSheet:(QWindow *)parent
{
QFileInfo info(*mCurrentSelection);
- NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath());
+ NSString *filepath = QCFString::toNSString(info.filePath());
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
[self updateProperties];
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
- [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
+ [mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""];
NSWindow *nsparent = static_cast<NSWindow *>(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent));
[mSavePanel beginSheetModalForWindow:nsparent completionHandler:^(NSInteger result){
@@ -322,8 +324,8 @@ static QString strippedText(QString s)
}
}
- QString qtFileName = QT_PREPEND_NAMESPACE(QCFString::toQString)(filename);
- QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
+ QString qtFileName = QCFString::toQString(filename);
+ QFileInfo info(qtFileName.normalized(QString::NormalizationForm_C));
QString path = info.absolutePath();
if (mCachedEntries->directory() != path) {
mCachedEntries->updateDirCache(path);
@@ -363,7 +365,7 @@ static QString strippedText(QString s)
if (filters.size() > 0){
for (int i=0; i<filters.size(); ++i) {
QString filter = hideDetails ? [self removeExtensions:filters.at(i)] : filters.at(i);
- [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(QCFString::toNSString)(filter)];
+ [mPopUpButton addItemWithTitle:QCFString::toNSString(filter)];
}
[mPopUpButton selectItemAtIndex:0];
[mSavePanel setAccessoryView:mAccessoryView];
@@ -391,18 +393,20 @@ static QString strippedText(QString s)
return mNameFilterDropDownList->value([mPopUpButton indexOfSelectedItem]);
}
-- (QStringList)selectedFiles
+- (QList<QUrl>)selectedFiles
{
if (mOpenPanel) {
- QStringList result;
+ QList<QUrl> result;
NSArray* array = [mOpenPanel URLs];
- for (NSUInteger i=0; i<[array count]; ++i)
- result << QCFString::toQString([[array objectAtIndex:i] path]).normalized(QString::NormalizationForm_C);
+ for (NSUInteger i=0; i<[array count]; ++i) {
+ QString path = QCFString::toQString([[array objectAtIndex:i] path]).normalized(QString::NormalizationForm_C);
+ result << QUrl::fromLocalFile(path);
+ }
return result;
} else {
- QStringList result;
- QString filename = QT_PREPEND_NAMESPACE(QCFString::toQString)([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
- result << filename.remove(QLatin1String("___qt_very_unlikely_prefix_"));
+ QList<QUrl> result;
+ QString filename = QCFString::toQString([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
+ result << QUrl::fromLocalFile(filename.remove(QLatin1String("___qt_very_unlikely_prefix_")));
return result;
}
}
@@ -412,18 +416,18 @@ static QString strippedText(QString s)
// Call this functions if mFileMode, mFileOptions,
// mNameFilterDropDownList or mQDirFilter changes.
// The savepanel does not contain the neccessary functions for this.
- const QT_PREPEND_NAMESPACE(QFileDialogOptions::FileMode) fileMode = mOptions->fileMode();
- bool chooseFilesOnly = fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFile)
- || fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFiles);
- bool chooseDirsOnly = fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::Directory)
- || fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::DirectoryOnly)
- || mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::ShowDirsOnly));
+ const QFileDialogOptions::FileMode fileMode = mOptions->fileMode();
+ bool chooseFilesOnly = fileMode == QFileDialogOptions::ExistingFile
+ || fileMode == QFileDialogOptions::ExistingFiles;
+ bool chooseDirsOnly = fileMode == QFileDialogOptions::Directory
+ || fileMode == QFileDialogOptions::DirectoryOnly
+ || mOptions->testOption(QFileDialogOptions::ShowDirsOnly);
[mOpenPanel setCanChooseFiles:!chooseDirsOnly];
[mOpenPanel setCanChooseDirectories:!chooseFilesOnly];
- [mSavePanel setCanCreateDirectories:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::ReadOnly)))];
- [mOpenPanel setAllowsMultipleSelection:(fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFiles))];
- [mOpenPanel setResolvesAliases:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::DontResolveSymlinks)))];
+ [mSavePanel setCanCreateDirectories:!(mOptions->testOption(QFileDialogOptions::ReadOnly))];
+ [mOpenPanel setAllowsMultipleSelection:(fileMode == QFileDialogOptions::ExistingFiles)];
+ [mOpenPanel setResolvesAliases:!(mOptions->testOption(QFileDialogOptions::DontResolveSymlinks))];
[mOpenPanel setTitle:QCFString::toNSString(mOptions->windowTitle())];
[mSavePanel setTitle:QCFString::toNSString(mOptions->windowTitle())];
[mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead?
@@ -432,7 +436,7 @@ static QString strippedText(QString s)
const QString defaultSuffix = mOptions->defaultSuffix();
if (!ext.isEmpty() && !defaultSuffix.isEmpty())
ext.prepend(defaultSuffix);
- [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : QT_PREPEND_NAMESPACE(qt_mac_QStringListToNSMutableArray(ext))];
+ [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(ext)];
if ([mSavePanel respondsToSelector:@selector(isVisible)] && [mSavePanel isVisible]) {
if ([mSavePanel respondsToSelector:@selector(validateVisibleColumns)])
@@ -444,7 +448,7 @@ static QString strippedText(QString s)
{
Q_UNUSED(sender);
if (mHelper) {
- QString selection = QT_PREPEND_NAMESPACE(QCFString::toQString([[mSavePanel URL] path]));
+ QString selection = QCFString::toQString([[mSavePanel URL] path]);
if (selection != mCurrentSelection) {
*mCurrentSelection = selection;
mHelper->QNSOpenSavePanelDelegate_selectionChanged(selection);
@@ -462,7 +466,7 @@ static QString strippedText(QString s)
[mCurrentDir release];
mCurrentDir = [path retain];
- mHelper->QNSOpenSavePanelDelegate_directoryEntered(QT_PREPEND_NAMESPACE(QCFString::toQString(mCurrentDir)));
+ mHelper->QNSOpenSavePanelDelegate_directoryEntered(QCFString::toQString(mCurrentDir));
}
/*
@@ -489,7 +493,7 @@ static QString strippedText(QString s)
- (QString)removeExtensions:(const QString &)filter
{
- QRegExp regExp(QT_PREPEND_NAMESPACE(QString::fromLatin1)(QT_PREPEND_NAMESPACE(QPlatformFileDialogHelper::filterRegExp)));
+ QRegExp regExp(QString::fromLatin1(QPlatformFileDialogHelper::filterRegExp));
if (regExp.indexIn(filter) != -1)
return regExp.cap(1).trimmed();
return filter;
@@ -525,7 +529,7 @@ static QString strippedText(QString s)
(filterToUse == -1 && currentFilter.startsWith(selectedFilter)))
filterToUse = i;
QString filter = hideDetails ? [self removeExtensions:currentFilter] : currentFilter;
- [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(QCFString::toNSString)(filter)];
+ [mPopUpButton addItemWithTitle:QCFString::toNSString(filter)];
}
if (filterToUse != -1)
[mPopUpButton selectItemAtIndex:filterToUse];
@@ -563,13 +567,13 @@ QCocoaFileDialogHelper::~QCocoaFileDialogHelper()
if (!mDelegate)
return;
QCocoaAutoReleasePool pool;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate) release];
+ [reinterpret_cast<QNSOpenSavePanelDelegate *>(mDelegate) release];
mDelegate = 0;
}
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_selectionChanged(const QString &newPath)
{
- emit currentChanged(newPath);
+ emit currentChanged(QUrl::fromLocalFile(newPath));
}
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
@@ -584,7 +588,7 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_directoryEntered(const QString &newDir)
{
// ### fixme: priv->setLastVisitedDirectory(newDir);
- emit directoryEntered(newDir);
+ emit directoryEntered(QUrl::fromLocalFile(newDir));
}
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuIndex)
@@ -596,43 +600,45 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuInd
extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); // qglobal.cpp
-void QCocoaFileDialogHelper::setDirectory(const QString &directory)
+void QCocoaFileDialogHelper::setDirectory(const QUrl &directory)
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (delegate)
- [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory)]];
+ [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory.toLocalFile())]];
}
-QString QCocoaFileDialogHelper::directory() const
+QUrl QCocoaFileDialogHelper::directory() const
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
- if (delegate)
- return QCFString::toQString([[delegate->mSavePanel directoryURL] path]).normalized(QString::NormalizationForm_C);
- return QString();
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+ if (delegate) {
+ QString path = QCFString::toQString([[delegate->mSavePanel directoryURL] path]).normalized(QString::NormalizationForm_C);
+ return QUrl::fromLocalFile(path);
+ }
+ return QUrl();
}
-void QCocoaFileDialogHelper::selectFile(const QString &filename)
+void QCocoaFileDialogHelper::selectFile(const QUrl &filename)
{
- QString filePath = filename;
+ QString filePath = filename.toLocalFile();
if (QDir::isRelativePath(filePath))
- filePath = QFileInfo(directory(), filePath).filePath();
+ filePath = QFileInfo(directory().toLocalFile(), filePath).filePath();
// There seems to no way to select a file once the dialog is running.
// So do the next best thing, set the file's directory:
setDirectory(QFileInfo(filePath).absolutePath());
}
-QStringList QCocoaFileDialogHelper::selectedFiles() const
+QList<QUrl> QCocoaFileDialogHelper::selectedFiles() const
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (delegate)
return [delegate selectedFiles];
- return QStringList();
+ return QList<QUrl>();
}
void QCocoaFileDialogHelper::setFilter()
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return;
const SharedPointerFileDialogOptions &opts = options();
@@ -651,7 +657,7 @@ void QCocoaFileDialogHelper::selectNameFilter(const QString &filter)
return;
const int index = options()->nameFilters().indexOf(filter);
if (index != -1) {
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return;
[delegate->mPopUpButton selectItemAtIndex:index];
@@ -661,7 +667,7 @@ void QCocoaFileDialogHelper::selectNameFilter(const QString &filter)
QString QCocoaFileDialogHelper::selectedNameFilter() const
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return QString();
int index = [delegate->mPopUpButton indexOfSelectedItem];
@@ -695,11 +701,11 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate()
return;
QCocoaAutoReleasePool pool;
const SharedPointerFileDialogOptions &opts = options();
- const QStringList selectedFiles = opts->initiallySelectedFiles();
- const QString directory = opts->initialDirectory();
+ const QList<QUrl> selectedFiles = opts->initiallySelectedFiles();
+ const QUrl directory = opts->initialDirectory();
const bool selectDir = selectedFiles.isEmpty();
- QString selection(selectDir ? directory : selectedFiles.front());
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc]
+ QString selection(selectDir ? directory.toLocalFile() : selectedFiles.front().toLocalFile());
+ QNSOpenSavePanelDelegate *delegate = [[QNSOpenSavePanelDelegate alloc]
initWithAcceptMode:
selection
options:opts
@@ -711,7 +717,7 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate()
bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent)
{
createNSOpenSavePanelDelegate();
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return false;
if (windowModality == Qt::NonModal)
@@ -729,7 +735,7 @@ bool QCocoaFileDialogHelper::hideCocoaFilePanel()
// open regarding whether or not to go native:
return false;
} else {
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
[delegate closePanel];
// Even when we hide it, we are still using a
// native dialog, so return true:
@@ -744,7 +750,7 @@ void QCocoaFileDialogHelper::exec()
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
// showing a native modal dialog will fail.
QCocoaAutoReleasePool pool;
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if ([delegate runApplicationModalPanel])
emit accept();
else
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
index c1fef68f42..83aebba6d3 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
@@ -47,9 +47,6 @@
QT_BEGIN_NAMESPACE
-class QFontDialog;
-class QFontDialogPrivate;
-
class QCocoaFontDialogHelper : public QPlatformFontDialogHelper
{
public:
@@ -63,14 +60,6 @@ public:
void setCurrentFont(const QFont &);
QFont currentFont() const;
-
-protected:
- void createNSFontPanelDelegate();
- bool showCocoaFontPanel(Qt::WindowModality windowModality, QWindow *parent);
- bool hideCocoaFontPanel();
-
-private:
- void *mDelegate;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index a70ba3749f..91fb52eb6d 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -128,14 +128,18 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
- (void)finishOffWithCode:(NSInteger)code;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSFontPanelDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
-- (id)initWithDialogHelper:
- (QCocoaFontDialogHelper *)helper
+@implementation QNSFontPanelDelegate
+
+- (id)init
{
self = [super init];
mFontPanel = [NSFontPanel sharedFontPanel];
- mHelper = helper;
+ mHelper = 0;
+ mStolenContentView = 0;
+ mOkButton = 0;
+ mCancelButton = 0;
mResultCode = NSCancelButton;
mDialogIsExecuting = false;
mResultSet = false;
@@ -145,13 +149,32 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mFontPanel setRestorable:NO];
#endif
+ [mFontPanel setDelegate:self];
+ [[NSFontManager sharedFontManager] setDelegate:self];
+
+ [mFontPanel retain];
+ return self;
+}
+
+- (void)dealloc
+{
+ [self restoreOriginalContentView];
+ [mFontPanel setDelegate:nil];
+ [[NSFontManager sharedFontManager] setDelegate:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [super dealloc];
+}
+
+- (void)setDialogHelper:(QCocoaFontDialogHelper *)helper
+{
+ mHelper = helper;
+
[mFontPanel setTitle:QCFString::toNSString(helper->options()->windowTitle())];
if (mHelper->options()->testOption(QFontDialogOptions::NoButtons)) {
- mStolenContentView = 0;
- mOkButton = 0;
- mCancelButton = 0;
- } else {
+ [self restoreOriginalContentView];
+ } else if (!mStolenContentView) {
// steal the font panel's contents view
mStolenContentView = [mFontPanel contentView];
[mStolenContentView retain];
@@ -176,14 +199,22 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mCancelButton setAction:@selector(onCancelClicked)];
[mCancelButton setTarget:self];
}
+}
- [mFontPanel retain];
- return self;
+- (void)closePanel
+{
+ [mFontPanel close];
}
-- (void)dealloc
+- (void)windowDidResize:(NSNotification *)notification
{
- if (mOkButton) {
+ Q_UNUSED(notification);
+ [self relayout];
+}
+
+- (void)restoreOriginalContentView
+{
+ if (mStolenContentView) {
NSView *ourContentView = [mFontPanel contentView];
// return stolen stuff to its rightful owner
@@ -192,28 +223,17 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mOkButton release];
[mCancelButton release];
[ourContentView release];
+ mOkButton = 0;
+ mCancelButton = 0;
+ mStolenContentView = 0;
}
-
- [mFontPanel setDelegate:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
- [super dealloc];
-}
-
-- (void)closePanel
-{
- [mFontPanel close];
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (mOkButton)
- [self relayout];
}
- (void)relayout
{
+ if (!mOkButton)
+ return;
+
[self relayoutToContentSize:[[mStolenContentView superview] frame].size];
}
@@ -289,30 +309,32 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
NSFont *panelFont = [fontManager convertFont:selectedFont];
mQtFont = qfontForCocoaFont(panelFont, mQtFont);
- emit mHelper->currentFontChanged(mQtFont);
+ if (mHelper)
+ emit mHelper->currentFontChanged(mQtFont);
}
- (void)showModelessPanel
{
mDialogIsExecuting = false;
+ mResultSet = false;
[mFontPanel makeKeyAndOrderFront:mFontPanel];
}
- (BOOL)runApplicationModalPanel
{
mDialogIsExecuting = true;
- [mFontPanel setDelegate:self];
// Call processEvents in case the event dispatcher has been interrupted, and needs to do
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
[NSApp runModalForWindow:mFontPanel];
+ mDialogIsExecuting = false;
return (mResultCode == NSOKButton);
}
-- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode
+- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mResultCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected);
+ return (mResultCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (BOOL)windowShouldClose:(id)window
@@ -324,7 +346,8 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[self finishOffWithCode:NSCancelButton];
} else {
mResultSet = true;
- emit mHelper->reject();
+ if (mHelper)
+ emit mHelper->reject();
}
return true;
}
@@ -359,27 +382,101 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
QT_BEGIN_NAMESPACE
-QCocoaFontDialogHelper::QCocoaFontDialogHelper() :
- mDelegate(0)
+class QCocoaFontPanel
+{
+public:
+ QCocoaFontPanel()
+ {
+ mDelegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc] init];
+ }
+
+ ~QCocoaFontPanel()
+ {
+ [mDelegate release];
+ }
+
+ void init(QCocoaFontDialogHelper *helper)
+ {
+ [mDelegate setDialogHelper:helper];
+ }
+
+ void cleanup(QCocoaFontDialogHelper *helper)
+ {
+ if (mDelegate->mHelper == helper)
+ mDelegate->mHelper = 0;
+ }
+
+ bool exec()
+ {
+ // Note: If NSApp is not running (which is the case if e.g a top-most
+ // QEventLoop has been interrupted, and the second-most event loop has not
+ // yet been reactivated (regardless if [NSApp run] is still on the stack)),
+ // showing a native modal dialog will fail.
+ return [mDelegate runApplicationModalPanel];
+ }
+
+ bool show(Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_UNUSED(parent);
+ if (windowModality != Qt::WindowModal)
+ [mDelegate showModelessPanel];
+ // no need to show a Qt::WindowModal dialog here, because it's necessary to call exec() in that case
+ return true;
+ }
+
+ void hide()
+ {
+ [mDelegate closePanel];
+ }
+
+ QFont currentFont() const
+ {
+ return mDelegate->mQtFont;
+ }
+
+ void setCurrentFont(const QFont &font)
+ {
+ NSFontManager *mgr = [NSFontManager sharedFontManager];
+ const NSFont *nsFont = 0;
+
+ int weight = 5;
+ NSFontTraitMask mask = 0;
+ if (font.style() == QFont::StyleItalic) {
+ mask |= NSItalicFontMask;
+ }
+ if (font.weight() == QFont::Bold) {
+ weight = 9;
+ mask |= NSBoldFontMask;
+ }
+
+ QFontInfo fontInfo(font);
+ nsFont = [mgr fontWithFamily:QCFString::toNSString(fontInfo.family())
+ traits:mask
+ weight:weight
+ size:fontInfo.pointSize()];
+
+ [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
+ mDelegate->mQtFont = font;
+ }
+
+private:
+ QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *mDelegate;
+};
+
+Q_GLOBAL_STATIC(QCocoaFontPanel, sharedFontPanel)
+
+QCocoaFontDialogHelper::QCocoaFontDialogHelper()
{
}
QCocoaFontDialogHelper::~QCocoaFontDialogHelper()
{
- if (!mDelegate)
- return;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate) release];
- mDelegate = 0;
+ sharedFontPanel()->cleanup(this);
}
void QCocoaFontDialogHelper::exec()
{
- // Note: If NSApp is not running (which is the case if e.g a top-most
- // QEventLoop has been interrupted, and the second-most event loop has not
- // yet been reactivated (regardless if [NSApp run] is still on the stack)),
- // showing a native modal dialog will fail.
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- if ([delegate runApplicationModalPanel])
+ if (sharedFontPanel()->exec())
emit accept();
else
emit reject();
@@ -387,86 +484,26 @@ void QCocoaFontDialogHelper::exec()
bool QCocoaFontDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent)
{
- if (windowModality == Qt::WindowModal) {
- // Cocoa's shared font panel cannot be shown as a sheet
- return false;
- }
- return showCocoaFontPanel(windowModality, parent);
+ if (windowModality == Qt::WindowModal)
+ windowModality = Qt::ApplicationModal;
+ sharedFontPanel()->init(this);
+ return sharedFontPanel()->show(windowModality, parent);
}
void QCocoaFontDialogHelper::hide()
{
- if (!mDelegate)
- return;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mFontPanel close];
+ sharedFontPanel()->hide();
}
void QCocoaFontDialogHelper::setCurrentFont(const QFont &font)
{
- NSFontManager *mgr = [NSFontManager sharedFontManager];
- const NSFont *nsFont = 0;
-
- int weight = 5;
- NSFontTraitMask mask = 0;
- if (font.style() == QFont::StyleItalic) {
- mask |= NSItalicFontMask;
- }
- if (font.weight() == QFont::Bold) {
- weight = 9;
- mask |= NSBoldFontMask;
- }
-
- QFontInfo fontInfo(font);
- nsFont = [mgr fontWithFamily:QCFString::toNSString(fontInfo.family())
- traits:mask
- weight:weight
- size:fontInfo.pointSize()];
-
- if (!mDelegate)
- createNSFontPanelDelegate();
-
- [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
- static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mQtFont = font;
+ sharedFontPanel()->init(this);
+ sharedFontPanel()->setCurrentFont(font);
}
QFont QCocoaFontDialogHelper::currentFont() const
{
- if (!mDelegate)
- return QFont();
- return reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mQtFont;
-}
-
-void QCocoaFontDialogHelper::createNSFontPanelDelegate()
-{
- if (mDelegate)
- return;
-
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc]
- initWithDialogHelper:this];
-
- mDelegate = delegate;
-}
-
-bool QCocoaFontDialogHelper::showCocoaFontPanel(Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_UNUSED(parent);
- createNSFontPanelDelegate();
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- if (windowModality == Qt::NonModal)
- [delegate showModelessPanel];
- // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel()
- return true;
-}
-
-bool QCocoaFontDialogHelper::hideCocoaFontPanel()
-{
- if (!mDelegate){
- return false;
- } else {
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- [delegate closePanel];
- return true;
- }
+ return sharedFontPanel()->currentFont();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 3ade0a2a45..901efbfb39 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -53,6 +53,8 @@
#include <QtWidgets/QWidget>
#endif
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
//
@@ -320,7 +322,7 @@ QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
mustInit = false;
for (int i=0; i<NumEntries; ++i)
rev_entries[i] = entries[i];
- qSort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan);
+ std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan);
}
const QVector<KeyPair>::iterator i
= qBinaryFind(rev_entries.begin(), rev_entries.end(), key);
@@ -508,7 +510,6 @@ CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
CGColorSpaceRef colorSpace;
CGDirectDisplayID displayID;
- CMProfileRef displayProfile = 0;
if (widget == 0) {
displayID = CGMainDisplayID();
} else {
@@ -526,18 +527,11 @@ CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
return colorSpace;
- CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
- if (err == noErr) {
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
- } else if (widget) {
- return qt_mac_displayColorSpace(0); // fall back on main display
- }
-
+ colorSpace = CGDisplayCopyColorSpace(displayID);
if (colorSpace == 0)
colorSpace = CGColorSpaceCreateDeviceRGB();
m_displayColorSpaceHash.insert(displayID, colorSpace);
- CMCloseProfile(displayProfile);
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
void qt_mac_cleanUpMacColorSpaces();
@@ -810,20 +804,7 @@ CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy)
NULL,
false);
} else {
- // Try get a device color space. Using the device color space means
- // that the CGImage can be drawn to screen without per-pixel color
- // space conversion, at the cost of less color accuracy.
- CGColorSpaceRef cgColourSpaceRef = 0;
- CMProfileRef sysProfile;
- if (CMGetSystemProfile(&sysProfile) == noErr)
- {
- cgColourSpaceRef = CGColorSpaceCreateWithPlatformColorSpace(sysProfile);
- CMCloseProfile(sysProfile);
- }
-
- // Fall back to Generic RGB if a profile was not found.
- if (!cgColourSpaceRef)
- cgColourSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ CGColorSpaceRef cgColourSpaceRef = qt_mac_displayColorSpace(0);
// Create a CGBitmapInfo contiaining the image format.
// Support the 8-bit per component (A)RGB formats.
@@ -857,7 +838,6 @@ CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy)
NULL,
false,
kCGRenderingIntentDefault);
- CGColorSpaceRelease(cgColourSpaceRef);
}
CGDataProviderRelease(cgDataProviderRef);
return cgImage;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index fad743439e..6d1882f622 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -232,7 +232,7 @@ QCocoaIntegration::QCocoaIntegration()
qApp->setAttribute(Qt::AA_DontUseNativeMenuBar, false);
- NSApplication *cocoaApplication = [QT_MANGLE_NAMESPACE(QNSApplication) sharedApplication];
+ NSApplication *cocoaApplication = [QNSApplication sharedApplication];
qt_redirectNSApplicationSendEvent();
if (qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")) {
@@ -256,12 +256,12 @@ QCocoaIntegration::QCocoaIntegration()
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
// Set app delegate, link to the current delegate (if any)
- QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ QCocoaApplicationDelegate *newDelegate = [QCocoaApplicationDelegate sharedDelegate];
[newDelegate setReflectionDelegate:[cocoaApplication delegate]];
[cocoaApplication setDelegate:newDelegate];
// Load the application menu. This menu contains Preferences, Hide, Quit.
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
+ QCocoaMenuLoader *qtMenuLoader = [[QCocoaMenuLoader alloc] init];
qt_mac_loadMenuNib(qtMenuLoader);
[cocoaApplication setMenu:[qtMenuLoader menu]];
[newDelegate setMenuLoader:qtMenuLoader];
@@ -279,7 +279,7 @@ QCocoaIntegration::~QCocoaIntegration()
QCocoaAutoReleasePool pool;
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
// remove the apple event handlers installed by QCocoaApplicationDelegate
- QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *delegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate];
[delegate removeAppleEventHandlers];
// reset the application delegate
[[NSApplication sharedApplication] setDelegate: 0];
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 2e53000596..14b8dee101 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -74,7 +74,7 @@ NSString *qt_mac_removePrivateUnicode(NSString* string)
return string;
}
-static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+static inline QCocoaMenuLoader *getMenuLoader()
{
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
@@ -87,7 +87,9 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
@end
-@implementation QT_MANGLE_NAMESPACE(QCocoaMenuDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
+
+@implementation QCocoaMenuDelegate
- (id) initWithMenu:(QCocoaMenu*) m
{
@@ -220,11 +222,11 @@ QCocoaMenu::QCocoaMenu() :
m_tag(0),
m_menuBar(0)
{
- m_delegate = [[QT_MANGLE_NAMESPACE(QCocoaMenuDelegate) alloc] initWithMenu:this];
+ m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"];
[m_nativeMenu setAutoenablesItems:YES];
- m_nativeMenu.delegate = (QT_MANGLE_NAMESPACE(QCocoaMenuDelegate) *) m_delegate;
+ m_nativeMenu.delegate = (QCocoaMenuDelegate *) m_delegate;
[m_nativeItem setSubmenu:m_nativeMenu];
}
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index ddfa9fff96..0fea55ac68 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -52,7 +52,7 @@
static QList<QCocoaMenuBar*> static_menubars;
-static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+static inline QCocoaMenuLoader *getMenuLoader()
{
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
@@ -240,7 +240,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
}
}
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
[loader ensureAppMenuInMenu:mb->nsMenu()];
NSMutableSet *mergedItems = [[NSMutableSet setWithCapacity:0] retain];
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 6d8174c667..013f9931ff 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -52,7 +52,7 @@
#include <QtCore/QDebug>
-static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+static inline QCocoaMenuLoader *getMenuLoader()
{
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
@@ -199,7 +199,7 @@ NSMenuItem *QCocoaMenuItem::sync()
if ((m_role != NoRole && !m_textSynced) || m_merged) {
NSMenuItem *mergeItem = nil;
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
switch (m_role) {
case ApplicationSpecificRole:
mergeItem = [loader appSpecificMenuItem:reinterpret_cast<NSInteger>(this)];
@@ -326,7 +326,7 @@ QT_END_NAMESPACE
QString QCocoaMenuItem::mergeText()
{
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
if (m_native == [loader aboutMenuItem]) {
return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName());
} else if (m_native== [loader aboutQtMenuItem]) {
@@ -344,7 +344,7 @@ QString QCocoaMenuItem::mergeText()
QKeySequence QCocoaMenuItem::mergeAccel()
{
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
if (m_native == [loader preferencesMenuItem])
return QKeySequence(QKeySequence::Preferences);
else if (m_native == [loader quitMenuItem])
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h
index a45ec0fa89..e07da39995 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -92,9 +92,11 @@
- (NSArray *)mergeable;
@end
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuLoader);
+
QT_BEGIN_NAMESPACE
-void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader);
+void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader);
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 62b722d2d2..29fc0fb674 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE
and written to QDir::temp() before loading. (Earlier Qt versions used
to require having the nib file in the Qt GUI framework.)
*/
-void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader)
+void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader)
{
// Create qt_menu.nib dir in temp.
QDir temp = QDir::temp();
@@ -106,7 +106,7 @@ void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader)
QT_END_NAMESPACE
-@implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
+@implementation QCocoaMenuLoader
- (void)awakeFromNib
{
diff --git a/src/plugins/platforms/cocoa/qcocoaservices.mm b/src/plugins/platforms/cocoa/qcocoaservices.mm
index e4cec8c5f8..de4c688b71 100644
--- a/src/plugins/platforms/cocoa/qcocoaservices.mm
+++ b/src/plugins/platforms/cocoa/qcocoaservices.mm
@@ -55,7 +55,7 @@ bool QCocoaServices::openUrl(const QUrl &url)
const QString scheme = url.scheme();
if (scheme.isEmpty())
return openDocument(url);
- return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toString(QUrl::FullyEncoded))]];
+ return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QCFString::toNSString(url.toString(QUrl::FullyEncoded))]];
}
bool QCocoaServices::openDocument(const QUrl &url)
@@ -63,7 +63,7 @@ bool QCocoaServices::openDocument(const QUrl &url)
if (!url.isValid())
return false;
- return [[NSWorkspace sharedWorkspace] openFile:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toLocalFile())];
+ return [[NSWorkspace sharedWorkspace] openFile:QCFString::toNSString(url.toLocalFile())];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index af817bd4c5..194394d11a 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -264,6 +264,10 @@ QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts()
fonts.insert(QPlatformTheme::SmallFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
fonts.insert(QPlatformTheme::MiniFont, qt_mac_qfontForThemeFont(kThemeMiniSystemFont));
+ QFont* fixedFont = new QFont(QStringLiteral("Monaco"), fonts[QPlatformTheme::SystemFont]->pointSize());
+ fixedFont->setStyleHint(QFont::TypeWriter);
+ fonts.insert(QPlatformTheme::FixedFont, fixedFont);
+
return fonts;
}
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 99f533b33a..83c960d931 100755
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -135,12 +135,16 @@ QT_USE_NAMESPACE
-(id)initWithQMenu:(QPlatformMenu*)qmenu;
@end
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem);
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView);
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSMenu);
+
QT_BEGIN_NAMESPACE
class QSystemTrayIconSys
{
public:
QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) {
- item = [[QT_MANGLE_NAMESPACE(QNSStatusItem) alloc] initWithSysTray:sys];
+ item = [[QNSStatusItem alloc] initWithSysTray:sys];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item];
@@ -156,7 +160,7 @@ public:
#endif
[item release];
}
- QT_MANGLE_NAMESPACE(QNSStatusItem) *item;
+ QNSStatusItem *item;
};
void QCocoaSystemTrayIcon::init()
@@ -310,8 +314,8 @@ QT_END_NAMESPACE
@implementation NSStatusItem (Qt)
@end
-@implementation QT_MANGLE_NAMESPACE(QNSImageView)
--(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent {
+@implementation QNSImageView
+-(id)initWithParent:(QNSStatusItem*)myParent {
self = [super init];
parent = myParent;
down = NO;
@@ -406,7 +410,7 @@ QT_END_NAMESPACE
}
@end
-@implementation QT_MANGLE_NAMESPACE(QNSStatusItem)
+@implementation QNSStatusItem
-(id)initWithSysTray:(QCocoaSystemTrayIcon *)sys
{
@@ -416,7 +420,7 @@ QT_END_NAMESPACE
menu = 0;
menuVisible = false;
systray = sys;
- imageCell = [[QT_MANGLE_NAMESPACE(QNSImageView) alloc] initWithParent:self];
+ imageCell = [[QNSImageView alloc] initWithParent:self];
[item setView: imageCell];
}
return self;
@@ -494,7 +498,7 @@ private:
QSystemTrayIconQMenu();
};
-@implementation QT_MANGLE_NAMESPACE(QNSMenu)
+@implementation QNSMenu
-(id)initWithQMenu:(QPlatformMenu*)qm {
self = [super init];
if (self) {
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index cac059763d..e4237c9b3e 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -68,7 +68,9 @@ public:
const QPalette *palette(Palette type = SystemPalette) const;
const QFont *font(Font type = SystemFont) const;
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
- QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
+ QPixmap fileIconPixmap(const QFileInfo &fileInfo,
+ const QSizeF &size,
+ QPlatformTheme::IconOptions options = 0) const;
QVariant themeHint(ThemeHint hint) const;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 13a387a0a3..1484ae2ba3 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -249,8 +249,10 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
return QPlatformTheme::standardPixmap(sp, size);
}
-QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
+QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions) const
{
+ Q_UNUSED(iconOptions);
QCocoaAutoReleasePool pool;
NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo.canonicalFilePath())];
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index b82d096bb5..8967445f59 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -61,7 +61,7 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow)
@end
@interface QNSPanel : NSPanel {
- @public QT_PREPEND_NAMESPACE(QCocoaWindow) *m_cocoaPlatformWindow;
+ @public QCocoaWindow *m_cocoaPlatformWindow;
}
- (void)clearPlatformWindow;
- (BOOL)canBecomeKeyWindow;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index c239aedb05..5fc2975a9d 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -155,6 +155,9 @@ static bool isMouseEvent(NSEvent *ev)
- (BOOL)canBecomeKeyWindow
{
+ if (!m_cocoaPlatformWindow)
+ return NO;
+
// Only tool or dialog windows should become key:
if (m_cocoaPlatformWindow
&& (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 3ee994427b..ca2a15a1cc 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -110,6 +110,10 @@ QT_END_NAMESPACE
- (void)otherMouseUp:(NSEvent *)theEvent;
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent;
+- (void)handleTabletEvent: (NSEvent *)theEvent;
+- (void)tabletPoint: (NSEvent *)theEvent;
+- (void)tabletProximity: (NSEvent *)theEvent;
+
- (int) convertKeyCode : (QChar)keyCode;
+ (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags;
- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index c2ffe96f8c..b8a31329fe 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -489,7 +489,7 @@ static QTouchDevice *touchDevice = 0;
return YES;
}
-- (void)convertFromEvent:(NSEvent *)event toWindowPoint:(QPoint *)qtWindowPoint andScreenPoint:(QPoint *)qtScreenPoint
+- (void)convertFromEvent:(NSEvent *)event toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint
{
// Calculate the mouse position in the QWindow and Qt screen coordinate system,
// starting from coordinates in the NSWindow coordinate system.
@@ -512,19 +512,19 @@ static QTouchDevice *touchDevice = 0;
NSPoint nsWindowPoint = [event locationInWindow]; // NSWindow coordinates
NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil]; // NSView/QWindow coordinates
- *qtWindowPoint = QPoint(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates
+ *qtWindowPoint = QPointF(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates
NSWindow *window = [self window];
// Use convertRectToScreen if available (added in 10.7).
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if ([window respondsToSelector:@selector(convertRectToScreen:)]) {
NSRect screenRect = [window convertRectToScreen : NSMakeRect(nsWindowPoint.x, nsWindowPoint.y, 0, 0)]; // OS X screen coordinates
- *qtScreenPoint = QPoint(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y)); // Qt screen coordinates
+ *qtScreenPoint = QPointF(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y)); // Qt screen coordinates
} else
#endif
{
NSPoint screenPoint = [window convertBaseToScreen : NSMakePoint(nsWindowPoint.x, nsWindowPoint.y)];
- *qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
+ *qtScreenPoint = QPointF(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
}
}
@@ -535,7 +535,10 @@ static QTouchDevice *touchDevice = 0;
- (void)handleMouseEvent:(NSEvent *)theEvent
{
- QPoint qtWindowPoint, qtScreenPoint;
+ [self handleTabletEvent: theEvent];
+
+ QPointF qtWindowPoint;
+ QPointF qtScreenPoint;
[self convertFromEvent:theEvent toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
ulong timestamp = [theEvent timestamp] * 1000;
@@ -676,9 +679,10 @@ static QTouchDevice *touchDevice = 0;
if (m_window->flags() & Qt::WindowTransparentForInput)
return [super mouseMoved:theEvent];
- QPoint windowPoint, screenPoint;
+ QPointF windowPoint;
+ QPointF screenPoint;
[self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint);
+ QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
// Top-level windows generate enter-leave events for sub-windows.
// Qt wants to know which window (if any) will be entered at the
@@ -709,9 +713,10 @@ static QTouchDevice *touchDevice = 0;
if (!m_platformWindow->m_nsWindow)
return;
- QPoint windowPoint, screenPoint;
+ QPointF windowPoint;
+ QPointF screenPoint;
[self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- m_platformWindow->m_underMouseWindow = m_platformWindow->childWindowAt(windowPoint);
+ m_platformWindow->m_underMouseWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_underMouseWindow, windowPoint, screenPoint);
}
@@ -779,6 +784,162 @@ static QTouchDevice *touchDevice = 0;
[self handleMouseEvent:theEvent];
}
+struct QCocoaTabletDeviceData
+{
+ QTabletEvent::TabletDevice device;
+ QTabletEvent::PointerType pointerType;
+ uint capabilityMask;
+ qint64 uid;
+};
+
+typedef QHash<uint, QCocoaTabletDeviceData> QCocoaTabletDeviceDataHash;
+Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash)
+
+- (void)handleTabletEvent: (NSEvent *)theEvent
+{
+ NSEventType eventType = [theEvent type];
+ if (eventType != NSTabletPoint && [theEvent subtype] != NSTabletPointEventSubtype)
+ return; // Not a tablet event.
+
+ ulong timestamp = [theEvent timestamp] * 1000;
+
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent: theEvent toWindowPoint: &windowPoint andScreenPoint: &screenPoint];
+
+ uint deviceId = [theEvent deviceID];
+ if (!tabletDeviceDataHash->contains(deviceId)) {
+ qWarning("QNSView handleTabletEvent: This tablet device is unknown"
+ " (received no proximity event for it). Discarding event.");
+ return;
+ }
+ const QCocoaTabletDeviceData &deviceData = tabletDeviceDataHash->value(deviceId);
+
+ bool down = (eventType != NSMouseMoved);
+
+ qreal pressure;
+ if (down) {
+ pressure = [theEvent pressure];
+ } else {
+ pressure = 0.0;
+ }
+
+ NSPoint tilt = [theEvent tilt];
+ int xTilt = qRound(tilt.x * 60.0);
+ int yTilt = qRound(tilt.y * -60.0);
+ qreal tangentialPressure = 0;
+ qreal rotation = 0;
+ int z = 0;
+ if (deviceData.capabilityMask & 0x0200)
+ z = [theEvent absoluteZ];
+
+ if (deviceData.capabilityMask & 0x0800)
+ tangentialPressure = [theEvent tangentialPressure];
+
+ rotation = [theEvent rotation];
+
+ Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
+
+ QWindowSystemInterface::handleTabletEvent(m_window, timestamp, down, windowPoint, screenPoint,
+ deviceData.device, deviceData.pointerType, pressure, xTilt, yTilt,
+ tangentialPressure, rotation, z, deviceData.uid,
+ keyboardModifiers);
+}
+
+- (void)tabletPoint: (NSEvent *)theEvent
+{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super tabletPoint:theEvent];
+
+ [self handleTabletEvent: theEvent];
+}
+
+static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
+{
+ qint64 uid = [theEvent uniqueID];
+ uint bits = [theEvent vendorPointingDeviceType];
+ if (bits == 0 && uid != 0) {
+ // Fallback. It seems that the driver doesn't always include all the information.
+ // High-End Wacom devices store their "type" in the uper bits of the Unique ID.
+ // I'm not sure how to handle it for consumer devices, but I'll test that in a bit.
+ bits = uid >> 32;
+ }
+
+ QTabletEvent::TabletDevice device;
+ // Defined in the "EN0056-NxtGenImpGuideX"
+ // on Wacom's Developer Website (www.wacomeng.com)
+ if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) {
+ device = QTabletEvent::Stylus;
+ } else {
+ switch (bits & 0x0F06) {
+ case 0x0802:
+ device = QTabletEvent::Stylus;
+ break;
+ case 0x0902:
+ device = QTabletEvent::Airbrush;
+ break;
+ case 0x0004:
+ device = QTabletEvent::FourDMouse;
+ break;
+ case 0x0006:
+ device = QTabletEvent::Puck;
+ break;
+ case 0x0804:
+ device = QTabletEvent::RotationStylus;
+ break;
+ default:
+ device = QTabletEvent::NoDevice;
+ }
+ }
+ return device;
+}
+
+- (void)tabletProximity: (NSEvent *)theEvent
+{
+ if (m_window->flags() & Qt::WindowTransparentForInput)
+ return [super tabletProximity:theEvent];
+
+ ulong timestamp = [theEvent timestamp] * 1000;
+
+ QCocoaTabletDeviceData deviceData;
+ deviceData.uid = [theEvent uniqueID];
+ deviceData.capabilityMask = [theEvent capabilityMask];
+
+ switch ([theEvent pointingDeviceType]) {
+ case NSUnknownPointingDevice:
+ default:
+ deviceData.pointerType = QTabletEvent::UnknownPointer;
+ break;
+ case NSPenPointingDevice:
+ deviceData.pointerType = QTabletEvent::Pen;
+ break;
+ case NSCursorPointingDevice:
+ deviceData.pointerType = QTabletEvent::Cursor;
+ break;
+ case NSEraserPointingDevice:
+ deviceData.pointerType = QTabletEvent::Eraser;
+ break;
+ }
+
+ deviceData.device = wacomTabletDevice(theEvent);
+
+ // The deviceID is "unique" while in the proximity, it's a key that we can use for
+ // linking up QCocoaTabletDeviceData to an event (especially if there are two devices in action).
+ bool entering = [theEvent isEnteringProximity];
+ uint deviceId = [theEvent deviceID];
+ if (entering) {
+ tabletDeviceDataHash->insert(deviceId, deviceData);
+ } else {
+ tabletDeviceDataHash->remove(deviceId);
+ }
+
+ if (entering) {
+ QWindowSystemInterface::handleTabletEnterProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
+ } else {
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
+ }
+}
+
- (void)touchesBeganWithEvent:(NSEvent *)event
{
const NSTimeInterval timestamp = [event timestamp];
@@ -859,7 +1020,8 @@ static QTouchDevice *touchDevice = 0;
}
#endif
- QPoint qt_windowPoint, qt_screenPoint;
+ QPointF qt_windowPoint;
+ QPointF qt_screenPoint;
[self convertFromEvent:theEvent toWindowPoint:&qt_windowPoint andScreenPoint:&qt_screenPoint];
NSTimeInterval timestamp = [theEvent timestamp];
ulong qt_timestamp = timestamp * 1000;
@@ -878,7 +1040,23 @@ static QTouchDevice *touchDevice = 0;
currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
}
- QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers);
+ Qt::ScrollPhase ph = Qt::ScrollUpdate;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ // On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
+ if (phase == NSEventPhaseMayBegin)
+ ph = Qt::ScrollBegin;
+ } else
+#endif
+ if (phase == NSEventPhaseBegan) {
+ // On 10.7, MayBegin will not happen, so Began is the actual beginning.
+ ph = Qt::ScrollBegin;
+ }
+ if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) {
+ ph = Qt::ScrollEnd;
+ }
+
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph);
if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled || phase == NSEventPhaseNone) {
currentWheelModifiers = Qt::NoModifier;
@@ -921,14 +1099,11 @@ static QTouchDevice *touchDevice = 0;
NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers];
NSString *characters = [nsevent characters];
- // [from Qt 4 impl] There is no way to get the scan code from carbon. But we cannot
+ // There is no way to get the scan code from carbon/cocoa. But we cannot
// use the value 0, since it indicates that the event originates from somewhere
// else than the keyboard.
quint32 nativeScanCode = 1;
-
- UInt32 nativeVirtualKey = 0;
- EventRef eventRef = EventRef([nsevent eventRef]);
- GetEventParameter(eventRef, kEventParamKeyCode, typeUInt32, 0, sizeof(nativeVirtualKey), 0, &nativeVirtualKey);
+ quint32 nativeVirtualKey = [nsevent keyCode];
QChar ch = QChar::ReplacementCharacter;
int keyCode = Qt::Key_unknown;
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index 301beb11c1..dc3757ce3c 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -362,7 +362,6 @@ CGColorSpaceRef QCoreGraphicsPaintEngine::macDisplayColorSpace(const QWidget *wi
CGColorSpaceRef colorSpace;
CGDirectDisplayID displayID;
- CMProfileRef displayProfile = 0;
if (widget == 0) {
displayID = CGMainDisplayID();
} else {
@@ -376,18 +375,11 @@ CGColorSpaceRef QCoreGraphicsPaintEngine::macDisplayColorSpace(const QWidget *wi
if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
return colorSpace;
- CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
- if (err == noErr) {
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
- } else if (widget) {
- return macDisplayColorSpace(0); // fall back on main display
- }
-
+ colorSpace = CGDisplayCopyColorSpace(displayID);
if (colorSpace == 0)
colorSpace = CGColorSpaceCreateDeviceRGB();
m_displayColorSpaceHash.insert(displayID, colorSpace);
- CMCloseProfile(displayProfile);
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
diff --git a/src/plugins/platforms/directfb/main.cpp b/src/plugins/platforms/directfb/main.cpp
index 3d5d60abaa..5ba1b0996b 100644
--- a/src/plugins/platforms/directfb/main.cpp
+++ b/src/plugins/platforms/directfb/main.cpp
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
class QDirectFbIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "directfb.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "directfb.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index 939d8c0686..5b4c958616 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -286,6 +286,14 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_MAIL , Qt::Key_LaunchMail);
insert(DIKS_FAVORITES , Qt::Key_Favorites);
+ insert(DIKS_RED , Qt::Key_Red);
+ insert(DIKS_GREEN , Qt::Key_Green);
+ insert(DIKS_YELLOW , Qt::Key_Yellow);
+ insert(DIKS_BLUE , Qt::Key_Blue);
+
+ insert(DIKS_CHANNEL_UP , Qt::Key_ChannelUp);
+ insert(DIKS_CHANNEL_DOWN , Qt::Key_ChannelDown);
+
insert(DIKS_BACK , Qt::Key_Back);
insert(DIKS_FORWARD , Qt::Key_Forward);
insert(DIKS_VOLUME_UP , Qt::Key_VolumeUp);
diff --git a/src/plugins/platforms/eglfs/main.cpp b/src/plugins/platforms/eglfs/main.cpp
index df77127b4a..d8e7a3792e 100644
--- a/src/plugins/platforms/eglfs/main.cpp
+++ b/src/plugins/platforms/eglfs/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QEglFSIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "eglfs.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "eglfs.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index cf1503b7f9..c2d04b17c8 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -74,6 +74,8 @@
QT_BEGIN_NAMESPACE
+static void *eglContextForContext(QOpenGLContext *context);
+
QEglFSIntegration::QEglFSIntegration()
: mEventDispatcher(createUnixEventDispatcher()), mFontDb(new QGenericUnixFontDatabase())
{
@@ -200,6 +202,20 @@ void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource
return 0;
}
+void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+
+ if (lowerCaseResource == "egldisplay") {
+ if (window && window->handle())
+ return static_cast<QEglFSScreen *>(window->handle()->screen())->display();
+ else
+ return static_cast<QEglFSScreen *>(mScreen)->display();
+ }
+
+ return 0;
+}
+
void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
QByteArray lowerCaseResource = resource.toLower();
@@ -215,6 +231,26 @@ void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QO
return 0;
}
+QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "get_egl_context")
+ return NativeResourceForContextFunction(eglContextForContext);
+
+ return 0;
+}
+
+static void *eglContextForContext(QOpenGLContext *context)
+{
+ Q_ASSERT(context);
+
+ QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle());
+ if (!handle)
+ return 0;
+
+ return handle->eglContext();
+}
+
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
{
class Chooser : public QEglConfigChooser {
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index bf044d6919..dd85788bd8 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -72,8 +72,11 @@ public:
// QPlatformNativeInterface
void *nativeResourceForIntegration(const QByteArray &resource);
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
+
QPlatformScreen *screen() const { return mScreen; }
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 6cb1f88c66..1fe8bcc11b 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
: m_dpy(dpy)
+ , m_surface(0)
, m_cursor(0)
{
#ifdef QEGL_EXTRA_DEBUG
@@ -95,4 +96,9 @@ QPlatformCursor *QEglFSScreen::cursor() const
return m_cursor;
}
+void QEglFSScreen::setPrimarySurface(EGLSurface surface)
+{
+ m_surface = surface;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 298a67cd3a..b04c85797f 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -69,9 +69,16 @@ public:
QPlatformCursor *cursor() const;
EGLDisplay display() const { return m_dpy; }
+ EGLSurface primarySurface() const { return m_surface; }
+
+protected:
+ void setPrimarySurface(EGLSurface surface);
private:
+ friend class QEglFSWindow;
+
EGLDisplay m_dpy;
+ EGLSurface m_surface;
QEglFSCursor *m_cursor;
};
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 28ce8c8a33..bf6e375ac0 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -42,6 +42,8 @@
#include "qeglfswindow.h"
#include "qeglfshooks.h"
#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformintegration.h>
+#include <private/qguiapplication_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
@@ -66,6 +68,11 @@ QEglFSWindow::~QEglFSWindow()
destroy();
}
+static inline bool supportsMultipleWindows()
+{
+ return QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows);
+}
+
void QEglFSWindow::create()
{
if (has_window)
@@ -80,6 +87,9 @@ void QEglFSWindow::create()
return;
}
+ if (!supportsMultipleWindows() && screen()->primarySurface())
+ return;
+
EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat());
m_config = QEglFSIntegration::chooseConfig(display, platformFormat);
@@ -105,11 +115,14 @@ void QEglFSWindow::resetSurface()
m_window = QEglFSHooks::hooks()->createNativeWindow(QEglFSHooks::hooks()->screenSize(), m_format);
has_window = true;
m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL);
+
if (m_surface == EGL_NO_SURFACE) {
EGLint error = eglGetError();
eglTerminate(display);
qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
}
+
+ screen()->setPrimarySurface(m_surface);
}
void QEglFSWindow::destroy()
@@ -117,6 +130,12 @@ void QEglFSWindow::destroy()
if (m_surface) {
EGLDisplay display = static_cast<QEglFSScreen *>(screen())->display();
eglDestroySurface(display, m_surface);
+
+ if (!supportsMultipleWindows()) {
+ // ours must be the primary surface
+ screen()->setPrimarySurface(0);
+ }
+
m_surface = 0;
}
@@ -145,9 +164,21 @@ WId QEglFSWindow::winId() const
return WId(m_window);
}
+EGLSurface QEglFSWindow::surface() const
+{
+ if (!supportsMultipleWindows())
+ return screen()->primarySurface();
+ return m_surface;
+}
+
QSurfaceFormat QEglFSWindow::format() const
{
return m_format;
}
+QEglFSScreen *QEglFSWindow::screen() const
+{
+ return static_cast<QEglFSScreen *>(QPlatformWindow::screen());
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index 0997f80e74..936537807a 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -59,9 +59,11 @@ public:
void setWindowState(Qt::WindowState state);
WId winId() const;
- EGLSurface surface() const { return m_surface; }
+ EGLSurface surface() const;
QSurfaceFormat format() const;
+ QEglFSScreen *screen() const;
+
void create();
void destroy();
diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro
index 842ff17f1c..5a2129eb08 100644
--- a/src/plugins/platforms/ios/ios.pro
+++ b/src/plugins/platforms/ios/ios.pro
@@ -1,3 +1,39 @@
-TEMPLATE = subdirs
+TARGET = qios
-SUBDIRS += plugin.pro qtmain.pro
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QIOSIntegrationPlugin
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private
+LIBS += -framework Foundation -framework UIKit -framework QuartzCore
+
+OBJECTIVE_SOURCES = \
+ plugin.mm \
+ qiosmain_wrapper.mm \
+ qiosmain_dummy.mm \
+ qiosintegration.mm \
+ qioswindow.mm \
+ qiosscreen.mm \
+ qiosbackingstore.mm \
+ qiosapplicationdelegate.mm \
+ qiosapplicationstate.mm \
+ qiosviewcontroller.mm \
+ qioscontext.mm \
+ qiosinputcontext.mm \
+ qiostheme.mm \
+ qiosglobal.mm
+
+HEADERS = \
+ qiosintegration.h \
+ qioswindow.h \
+ qiosscreen.h \
+ qiosbackingstore.h \
+ qiosapplicationdelegate.h \
+ qiosapplicationstate.h \
+ qiosviewcontroller.h \
+ qioscontext.h \
+ qiosinputcontext.h \
+ qiostheme.h \
+ qiosglobal.h
+
+#HEADERS = qiossoftwareinputhandler.h
diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm
index a93b6037ad..efb1ad8d74 100644
--- a/src/plugins/platforms/ios/plugin.mm
+++ b/src/plugins/platforms/ios/plugin.mm
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "ios.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
@@ -66,4 +66,8 @@ QT_END_NAMESPACE
#include "plugin.moc"
+// Dummy function that we explicitly tell the linker to look for,
+// so that the plugin's static initializer is included and run.
+extern "C" void qt_registerPlatformPlugin() {}
+
Q_IMPORT_PLUGIN(QIOSIntegrationPlugin)
diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro
deleted file mode 100644
index 591a0a67ed..0000000000
--- a/src/plugins/platforms/ios/plugin.pro
+++ /dev/null
@@ -1,36 +0,0 @@
-TARGET = qios
-
-PLUGIN_TYPE = platforms
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-LIBS += -framework UIKit -framework QuartzCore
-
-OBJECTIVE_SOURCES = \
- plugin.mm \
- qiosintegration.mm \
- qioswindow.mm \
- qiosscreen.mm \
- qioseventdispatcher.mm \
- qiosbackingstore.mm \
- qiosapplicationdelegate.mm \
- qiosviewcontroller.mm \
- qioscontext.mm \
- qiosinputcontext.mm \
- qiostheme.mm \
- qiosglobal.mm
-
-HEADERS = \
- qiosintegration.h \
- qioswindow.h \
- qiosscreen.h \
- qioseventdispatcher.h \
- qiosbackingstore.h \
- qiosapplicationdelegate.h \
- qiosviewcontroller.h \
- qioscontext.h \
- qiosinputcontext.h \
- qiostheme.h \
- qiosglobal.h
-
-#HEADERS = qiossoftwareinputhandler.h
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h
index 3d3ba58049..bfe31af198 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.h
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h
@@ -50,7 +50,3 @@
@property (strong, nonatomic) QIOSViewController *qiosViewController;
@end
-
-@interface QIOSMainWrapperApplicationDelegate : QIOSApplicationDelegate
-@end
-
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
index 10cbe529c4..52d94f38fb 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
@@ -39,10 +39,15 @@
**
****************************************************************************/
-#import "qiosapplicationdelegate.h"
+#include "qiosapplicationdelegate.h"
+
+#include "qiosviewcontroller.h"
#include "qioswindow.h"
+
#include <QtCore/QtCore>
+extern int qt_user_main(int argc, char *argv[]);
+
@implementation QIOSApplicationDelegate
@synthesize window;
@@ -50,40 +55,43 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
- Q_UNUSED(application)
- Q_UNUSED(launchOptions)
+ Q_UNUSED(application);
+ Q_UNUSED(launchOptions);
- return YES;
-}
+ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
+ self.qiosViewController = [[[QIOSViewController alloc] init] autorelease];
+ self.window.rootViewController = self.qiosViewController;
-- (void)applicationWillResignActive:(UIApplication *)application
-{
- Q_UNUSED(application)
-}
+#ifdef QT_DEBUG
+ self.window.backgroundColor = [UIColor cyanColor];
+#endif
-- (void)applicationDidEnterBackground:(UIApplication *)application
-{
- Q_UNUSED(application)
-}
+ [self.window makeKeyAndVisible];
-- (void)applicationWillEnterForeground:(UIApplication *)application
-{
- Q_UNUSED(application)
- // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
-}
+ // We schedule the main-redirection for the next eventloop pass so that we
+ // can return from this function and let UIApplicationMain finish its job.
+ [NSTimer scheduledTimerWithTimeInterval:.01f target:self
+ selector:@selector(runUserMain) userInfo:nil repeats:NO];
-- (void)applicationDidBecomeActive:(UIApplication *)application
-{
- Q_UNUSED(application)
- // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+ return YES;
}
-- (void)applicationWillTerminate:(UIApplication *)application
+- (void)runUserMain
{
- Q_UNUSED(application)
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+ NSArray *arguments = [[NSProcessInfo processInfo] arguments];
+ int argc = arguments.count;
+ char **argv = new char*[argc];
+ for (int i = 0; i < argc; ++i) {
+ NSString *arg = [arguments objectAtIndex:i];
+ argv[i] = reinterpret_cast<char *>(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]]));
+ strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ }
+
+ qt_user_main(argc, argv);
+ delete[] argv;
}
+
- (void)dealloc
{
[qiosViewController release];
@@ -93,4 +101,3 @@
@end
-
diff --git a/src/plugins/platforms/kms/qkmsudevhandler.h b/src/plugins/platforms/ios/qiosapplicationstate.h
index e95960628a..e726ad895e 100644
--- a/src/plugins/platforms/kms/qkmsudevhandler.h
+++ b/src/plugins/platforms/ios/qiosapplicationstate.h
@@ -39,26 +39,22 @@
**
****************************************************************************/
-#ifndef QKMSUDEVHANDLER_H
-#define QKMSUDEVHANDLER_H
-
-#include <QObject>
-
-#include <libudev.h>
+#ifndef QIOSAPPLICATIONSTATE_H
+#define QIOSAPPLICATIONSTATE_H
QT_BEGIN_NAMESPACE
-class QKmsUdevHandler : public QObject
-{
- Q_OBJECT
+@class QIOSApplicationStateListener;
+class QIOSApplicationState
+{
public:
- QKmsUdevHandler(QObject *parent = 0);
- virtual ~QKmsUdevHandler();
-
- virtual QObject *create(struct udev_device *) = 0;
+ QIOSApplicationState();
+ ~QIOSApplicationState();
+private:
+ QIOSApplicationStateListener *m_listener;
};
QT_END_NAMESPACE
-#endif // QKMSUDEVHANDLER_H
+#endif
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm
new file mode 100644
index 0000000000..df64edf465
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosapplicationstate.mm
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#include <qpa/qwindowsysteminterface.h>
+#include "qiosapplicationstate.h"
+
+@interface QIOSApplicationStateListener : NSObject
+@end
+
+@implementation QIOSApplicationStateListener
+
+- (id) init
+{
+ self = [super init];
+ if (self) {
+ // Listen for application state changes.
+ // Note: We use notifications rather than application delegate callbacks to
+ // also support hybrid applications were QIOSApplicationDelegate is not in use.
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(applicationDidBecomeActive)
+ name:UIApplicationDidBecomeActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(applicationWillResignActive)
+ name:UIApplicationWillResignActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(applicationDidEnterBackground)
+ name:UIApplicationDidEnterBackgroundNotification
+ object:nil];
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:UIApplicationDidBecomeActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:UIApplicationWillResignActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:UIApplicationDidEnterBackgroundNotification
+ object:nil];
+ [super dealloc];
+}
+
+- (void) applicationDidBecomeActive
+{
+ [self handleApplicationStateChanged:UIApplicationStateActive];
+}
+
+- (void) applicationWillResignActive
+{
+ // Note that UIApplication is still UIApplicationStateActive at this
+ // point, but since there is no separate notification for the inactive
+ // state, we report UIApplicationStateInactive now:
+ [self handleApplicationStateChanged:UIApplicationStateInactive];
+}
+
+- (void) applicationDidEnterBackground
+{
+ [self handleApplicationStateChanged:UIApplicationStateBackground];
+}
+
+- (void) handleApplicationStateChanged:(UIApplicationState) uiApplicationState
+{
+ Qt::ApplicationState state;
+ switch (uiApplicationState) {
+ case UIApplicationStateActive:
+ // The application is visible in front, and receiving events:
+ state = Qt::ApplicationActive;
+ break;
+ case UIApplicationStateInactive:
+ // The app is running in the foreground but is not receiving events. This
+ // typically happens while transitioning to/from active/background, like
+ // upon app launch or when receiving incoming calls:
+ state = Qt::ApplicationInactive;
+ break;
+ case UIApplicationStateBackground:
+ // Normally the app would enter this state briefly before it gets
+ // suspeded (you have five seconds, according to Apple).
+ // You can request more time and start a background task, which would
+ // normally map closer to Qt::ApplicationHidden. But since we have no
+ // API for doing that yet, we handle this state as "about to be suspended".
+ // Note: A screen-shot for the SpringBoard will also be taken after this
+ // call returns.
+ state = Qt::ApplicationSuspended;
+ break;
+ }
+ QWindowSystemInterface::handleApplicationStateChanged(state);
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+
+QIOSApplicationState::QIOSApplicationState()
+ : m_listener([[QIOSApplicationStateListener alloc] init])
+{
+ // Update the current state now, since we have missed all the updates
+ // posted from AppKit so far. But let QPA finish initialization first:
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIApplicationState state = [UIApplication sharedApplication].applicationState;
+ [m_listener handleApplicationStateChanged:state];
+ });
+}
+
+QIOSApplicationState::~QIOSApplicationState()
+{
+ [m_listener release];
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index 87bcc01d04..0c4bee1ef0 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -151,17 +151,17 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
}
- // Ensure that the FBO's buffers match the size of the window
+ // Ensure that the FBO's buffers match the size of the layer
QIOSWindow *platformWindow = static_cast<QIOSWindow *>(surface);
- if (framebufferObject.renderbufferWidth != platformWindow->effectiveWidth() ||
- framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) {
+ UIView *view = reinterpret_cast<UIView *>(platformWindow->winId());
+ CAEAGLLayer *layer = static_cast<CAEAGLLayer *>(view.layer);
+ if (framebufferObject.renderbufferWidth != (layer.frame.size.width * layer.contentsScale) ||
+ framebufferObject.renderbufferHeight != (layer.frame.size.height * layer.contentsScale)) {
[EAGLContext setCurrentContext:m_eaglContext];
glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle);
glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
- UIView *view = reinterpret_cast<UIView *>(platformWindow->winId());
- CAEAGLLayer *layer = static_cast<CAEAGLLayer *>(view.layer);
[m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth);
@@ -200,7 +200,7 @@ void QIOSContext::windowDestroyed(QObject *object)
QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName)
{
- return reinterpret_cast<QFunctionPointer>(dlsym(RTLD_NEXT, functionName.constData()));
+ return QFunctionPointer(dlsym(RTLD_DEFAULT, functionName.constData()));
}
#include "moc_qioscontext.cpp"
diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h
index 176ad05733..78c1b260e6 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.h
+++ b/src/plugins/platforms/ios/qiosinputcontext.h
@@ -66,6 +66,7 @@ public:
private:
QIOSKeyboardListener *m_keyboardListener;
UIView *m_focusView;
+ bool m_hasPendingHideRequest;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 1d3ab12de9..d430589037 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -99,6 +99,7 @@ QIOSInputContext::QIOSInputContext()
: QPlatformInputContext()
, m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
, m_focusView(0)
+ , m_hasPendingHideRequest(false)
{
}
@@ -120,12 +121,20 @@ void QIOSInputContext::showInputPanel()
// responder. Rather than searching for it from the top, we let the active QIOSWindow tell us which view to use.
// Note that Qt will forward keyevents to whichever QObject that needs it, regardless of which UIView the input
// actually came from. So in this respect, we're undermining iOS' responder chain.
+ m_hasPendingHideRequest = false;
[m_focusView becomeFirstResponder];
}
void QIOSInputContext::hideInputPanel()
{
- [m_focusView resignFirstResponder];
+ // Delay hiding the keyboard for cases where the user is transferring focus between
+ // 'line edits'. In that case the 'line edit' that lost focus will close the input
+ // panel, just to see that the new 'line edit' will open it again:
+ m_hasPendingHideRequest = true;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (m_hasPendingHideRequest)
+ [m_focusView resignFirstResponder];
+ });
}
bool QIOSInputContext::isInputPanelVisible() const
diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h
index c352e0f2d2..4aaf98f839 100644
--- a/src/plugins/platforms/ios/qiosintegration.h
+++ b/src/plugins/platforms/ios/qiosintegration.h
@@ -46,6 +46,8 @@
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qwindowsysteminterface.h>
+#include "qiosapplicationstate.h"
+
QT_BEGIN_NAMESPACE
class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
@@ -79,6 +81,7 @@ private:
QPlatformInputContext *m_inputContext;
QPlatformScreen *m_screen;
QTouchDevice *m_touchDevice;
+ QIOSApplicationState m_applicationState;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 61fd1c3d60..7fd6015a2f 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -43,12 +43,13 @@
#include "qioswindow.h"
#include "qiosbackingstore.h"
#include "qiosscreen.h"
-#include "qioseventdispatcher.h"
#include "qioscontext.h"
#include "qiosinputcontext.h"
#include "qiostheme.h"
+#include <QtPlatformSupport/private/qeventdispatcher_cf_p.h>
#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
+#include <QDir>
#include <QtDebug>
@@ -71,6 +72,9 @@ QIOSIntegration::QIOSIntegration()
exit(-1);
}
+ // Set current directory to app bundle folder
+ QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
+
screenAdded(m_screen);
m_touchDevice = new QTouchDevice;
@@ -86,6 +90,8 @@ bool QIOSIntegration::hasCapability(Capability cap) const
return true;
case MultipleWindows:
return true;
+ case ApplicationState:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
@@ -111,7 +117,7 @@ QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLCont
QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const
{
- return new QIOSEventDispatcher();
+ return new QEventDispatcherCoreFoundation;
}
QPlatformFontDatabase * QIOSIntegration::fontDatabase() const
@@ -129,6 +135,8 @@ QVariant QIOSIntegration::styleHint(StyleHint hint) const
switch (hint) {
case ShowIsFullScreen:
return true;
+ case SetFocusOnTouchRelease:
+ return true;
default:
return QPlatformIntegration::styleHint(hint);
}
diff --git a/src/plugins/platforminputcontexts/maliit/serverproxy.cpp b/src/plugins/platforms/ios/qiosmain_dummy.mm
index fe104c23f9..28d7e59381 100644
--- a/src/plugins/platforminputcontexts/maliit/serverproxy.cpp
+++ b/src/plugins/platforms/ios/qiosmain_dummy.mm
@@ -39,18 +39,18 @@
**
****************************************************************************/
-#include "serverproxy.h"
+#include <QtCore/qglobal.h>
/*
- * Implementation of interface class ComMeegoInputmethodUiserver1Interface
- */
+ This file provides a dummy implementation of qt_user_main, so that
+ we don't get an undefined symbol in the hybrid use-case, where we
+ don't rename main() to qt_user_main(). As long as the linker is not
+ passed -all_load, this translation unit is only picked up and used
+ if qt_user_main is not defined by the user's code.
+*/
-ComMeegoInputmethodUiserver1Interface::ComMeegoInputmethodUiserver1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
- : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+int qt_user_main(int, char **)
{
+ qFatal("Hit dummy qt_user_main, this should never happen!");
+ return 0;
}
-
-ComMeegoInputmethodUiserver1Interface::~ComMeegoInputmethodUiserver1Interface()
-{
-}
-
diff --git a/src/plugins/platforms/kms/qkmsudevdrmhandler.cpp b/src/plugins/platforms/ios/qiosmain_wrapper.mm
index 68a4aaacdb..d9b8c7311e 100644
--- a/src/plugins/platforms/kms/qkmsudevdrmhandler.cpp
+++ b/src/plugins/platforms/ios/qiosmain_wrapper.mm
@@ -39,28 +39,22 @@
**
****************************************************************************/
-#include <QtCore/QRegExp>
+#include "qiosapplicationdelegate.h"
-#include <qkmsintegration.h>
-#include <qkmsudevdrmhandler.h>
+/*
+ This file provides a wrapper implementation of main() for the non-
+ hybrid use-case. The user's main is renamed to qt_user_main by the
+ build rules, and we'll call out to that main at the appropriate time.
-QT_BEGIN_NAMESPACE
+ This file purposly only exports a single symbol, _main, so that
+ when the linker considers the translation unit for inclusion it
+ will discard it when main has already been defined in the user's
+ application for the hybrid use-case.
+*/
-QKmsUdevDRMHandler::QKmsUdevDRMHandler(QKmsIntegration *integration)
- : m_integration(integration)
+int main(int argc, char *argv[])
{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));
+ }
}
-
-QObject *QKmsUdevDRMHandler::create(struct udev_device *device)
-{
- if (strcmp(udev_device_get_subsystem(device), "drm"))
- return 0;
-
- QRegExp regexp("^card\\d+$");
- if (!regexp.exactMatch(udev_device_get_sysname(device)))
- return 0;
-
- return m_integration->createDevice(udev_device_get_devnode(device));
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 0c3ae8e834..c8d0f823f6 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -183,12 +183,6 @@
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
- QWindow *window = m_qioswindow->window();
-
- // Transfer focus to the touched window:
- if (window != QGuiApplication::focusWindow())
- m_qioswindow->requestActivateWindow();
-
// UIKit generates [Began -> Moved -> Ended] event sequences for
// each touch point. Internally we keep a hashmap of active UITouch
// points to QWindowSystemInterface::TouchPoints, and assigns each TouchPoint
@@ -210,6 +204,14 @@
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
+ QWindow *window = m_qioswindow->window();
+ if (window != QGuiApplication::focusWindow() && m_activeTouches.size() == 1) {
+ // Activate the touched window if the last touch was released inside it:
+ UITouch *touch = static_cast<UITouch *>([[touches allObjects] lastObject]);
+ if (CGRectContainsPoint([self bounds], [touch locationInView:self]))
+ m_qioswindow->requestActivateWindow();
+ }
+
[self updateTouchList:touches withState:Qt::TouchPointReleased];
[self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)];
@@ -247,6 +249,23 @@
return YES;
}
+- (BOOL)becomeFirstResponder
+{
+ // On iOS, a QWindow should only have input focus when the input panel is
+ // open. This is to stop cursors and focus rects from being drawn when the
+ // user cannot type. And since the keyboard will open when a view becomes
+ // the first responder, it's now a good time to inform QPA that the QWindow
+ // this view backs became active:
+ QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
+ return [super becomeFirstResponder];
+}
+
+- (BOOL)resignFirstResponder
+{
+ QWindowSystemInterface::handleWindowActivated(0);
+ return [super resignFirstResponder];
+}
+
- (BOOL)hasText
{
return YES;
@@ -416,7 +435,6 @@ void QIOSWindow::requestActivateWindow()
raise();
QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
static_cast<QIOSInputContext *>(context)->focusViewChanged(m_view);
- QPlatformWindow::requestActivateWindow();
}
void QIOSWindow::raiseOrLower(bool raise)
diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm
deleted file mode 100644
index 19c98f2c59..0000000000
--- a/src/plugins/platforms/ios/qtmain.mm
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** 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, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qiosapplicationdelegate.h"
-#include "qiosviewcontroller.h"
-
-int main(int argc, char *argv[])
-{
- @autoreleasepool {
- return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSMainWrapperApplicationDelegate class]));
- }
-}
-
-extern int qt_main(int argc, char *argv[]);
-
-@implementation QIOSMainWrapperApplicationDelegate
-
-- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
-{
- self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
- self.qiosViewController = [[[QIOSViewController alloc] init] autorelease];
- self.window.rootViewController = self.qiosViewController;
-
-#ifdef QT_DEBUG
- self.window.backgroundColor = [UIColor cyanColor];
-#endif
-
- [self.window makeKeyAndVisible];
-
- // We schedule the main-redirection for the next eventloop pass so that we
- // can return from this function and let UIApplicationMain finish its job.
- [NSTimer scheduledTimerWithTimeInterval:.01f target:self
- selector:@selector(runUserMain) userInfo:nil repeats:NO];
-
- if ([QIOSApplicationDelegate instancesRespondToSelector:_cmd])
- return [super application:application didFinishLaunchingWithOptions:launchOptions];
- else
- return YES;
-}
-
-- (void)runUserMain
-{
- NSArray *arguments = [[NSProcessInfo processInfo] arguments];
- int argc = arguments.count;
- char **argv = new char*[argc];
- for (int i = 0; i < argc; ++i) {
- NSString *arg = [arguments objectAtIndex:i];
- argv[i] = reinterpret_cast<char *>(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]]));
- strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- }
-
- qt_main(argc, argv);
- delete[] argv;
-}
-
-@end
diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro
deleted file mode 100644
index cbcb272217..0000000000
--- a/src/plugins/platforms/ios/qtmain.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-TARGET = qiosmain
-
-PLUGIN_TYPE = platforms
-load(qt_plugin)
-
-QT += gui-private
-
-OBJECTIVE_SOURCES = qtmain.mm
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
index 711cf9e5c7..612a878736 100644
--- a/src/plugins/platforms/kms/kms.pro
+++ b/src/plugins/platforms/kms/kms.pro
@@ -22,9 +22,6 @@ SOURCES = main.cpp \
qkmsdevice.cpp \
qkmsbackingstore.cpp \
qkmsnativeinterface.cpp \
- qkmsudevlistener.cpp \
- qkmsudevhandler.cpp \
- qkmsudevdrmhandler.cpp \
qkmsvthandler.cpp
HEADERS = qkmsintegration.h \
qkmsscreen.h \
@@ -34,9 +31,6 @@ HEADERS = qkmsintegration.h \
qkmsdevice.h \
qkmsbackingstore.h \
qkmsnativeinterface.h \
- qkmsudevlistener.h \
- qkmsudevhandler.h \
- qkmsudevdrmhandler.h \
qkmsvthandler.h
OTHER_FILES += \
diff --git a/src/plugins/platforms/kms/main.cpp b/src/plugins/platforms/kms/main.cpp
index 75f7ef5278..db0582e694 100644
--- a/src/plugins/platforms/kms/main.cpp
+++ b/src/plugins/platforms/kms/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "kms.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "kms.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
index 8210b54535..539363722d 100644
--- a/src/plugins/platforms/kms/qkmsintegration.cpp
+++ b/src/plugins/platforms/kms/qkmsintegration.cpp
@@ -46,10 +46,14 @@
#include "qkmsbackingstore.h"
#include "qkmscontext.h"
#include "qkmsnativeinterface.h"
-#include "qkmsudevlistener.h"
-#include "qkmsudevdrmhandler.h"
#include "qkmsvthandler.h"
+#if !defined(QT_NO_EVDEV)
+#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
+#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
+#include <QtPlatformSupport/private/qevdevtouch_p.h>
+#endif
+
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -62,18 +66,32 @@ QKmsIntegration::QKmsIntegration()
: QPlatformIntegration(),
m_fontDatabase(new QGenericUnixFontDatabase()),
m_eventDispatcher(createUnixEventDispatcher()),
- m_nativeInterface(new QKmsNativeInterface),
- m_udevListener(new QKmsUdevListener)
+ m_nativeInterface(new QKmsNativeInterface)
{
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
setenv("EGL_PLATFORM", "drm",1);
m_vtHandler = new QKmsVTHandler;
- m_drmHandler = new QKmsUdevDRMHandler(this);
- m_udevListener->addHandler(m_drmHandler);
+
+ m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_DRM | QDeviceDiscovery::Device_DRM_PrimaryGPU, 0);
+ if (m_deviceDiscovery) {
+ QStringList devices = m_deviceDiscovery->scanConnectedDevices();
+ foreach (QString device, devices)
+ addDevice(device);
+
+ connect(m_deviceDiscovery, SIGNAL(deviceDetected(QString)), this, SLOT(addDevice(QString)));
+ connect(m_deviceDiscovery, SIGNAL(deviceRemoved(QString)), this, SLOT(removeDevice(QString)));
+ }
+
+#if !defined(QT_NO_EVDEV)
+ new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
+ new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
+ new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
+#endif
}
QKmsIntegration::~QKmsIntegration()
{
+ delete m_deviceDiscovery;
foreach (QKmsDevice *device, m_devices) {
delete device;
}
@@ -81,15 +99,18 @@ QKmsIntegration::~QKmsIntegration()
delete screen;
}
delete m_fontDatabase;
- delete m_udevListener;
delete m_vtHandler;
}
-QObject *QKmsIntegration::createDevice(const char *path)
+void QKmsIntegration::addDevice(const QString &deviceNode)
+{
+ m_devices.append(new QKmsDevice(deviceNode, this));
+}
+
+void QKmsIntegration::removeDevice(const QString &deviceNode)
{
- QKmsDevice *device = new QKmsDevice(path, this);
- m_devices.append(device);
- return device;
+ // TODO: support hot-plugging some day?
+ Q_UNUSED(deviceNode);
}
bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
index c08396ba3f..5069753aa5 100644
--- a/src/plugins/platforms/kms/qkmsintegration.h
+++ b/src/plugins/platforms/kms/qkmsintegration.h
@@ -44,17 +44,18 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
+#include <QtPlatformSupport/private/qdevicediscovery_p.h>
QT_BEGIN_NAMESPACE
class QKmsScreen;
class QKmsDevice;
-class QKmsUdevListener;
-class QKmsUdevDRMHandler;
class QKmsVTHandler;
-class QKmsIntegration : public QPlatformIntegration
+class QKmsIntegration : public QObject, public QPlatformIntegration
{
+ Q_OBJECT
+
public:
QKmsIntegration();
~QKmsIntegration();
@@ -73,6 +74,10 @@ public:
void addScreen(QKmsScreen *screen);
QObject *createDevice(const char *);
+private slots:
+ void addDevice(const QString &deviceNode);
+ void removeDevice(const QString &deviceNode);
+
private:
QStringList findDrmDevices();
@@ -81,9 +86,8 @@ private:
QPlatformFontDatabase *m_fontDatabase;
QAbstractEventDispatcher *m_eventDispatcher;
QPlatformNativeInterface *m_nativeInterface;
- QKmsUdevListener *m_udevListener;
- QKmsUdevDRMHandler *m_drmHandler;
QKmsVTHandler *m_vtHandler;
+ QDeviceDiscovery *m_deviceDiscovery;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/linuxfb/main.cpp b/src/plugins/platforms/linuxfb/main.cpp
index a1037c4feb..579984d2fc 100644
--- a/src/plugins/platforms/linuxfb/main.cpp
+++ b/src/plugins/platforms/linuxfb/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QLinuxFbIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "linuxfb.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "linuxfb.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/minimal/main.cpp b/src/plugins/platforms/minimal/main.cpp
index 811f1fe5ee..7846b5b387 100644
--- a/src/plugins/platforms/minimal/main.cpp
+++ b/src/plugins/platforms/minimal/main.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class QMinimalIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "minimal.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "minimal.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/minimalegl/main.cpp b/src/plugins/platforms/minimalegl/main.cpp
index 414f45c745..c951bfb0dc 100644
--- a/src/plugins/platforms/minimalegl/main.cpp
+++ b/src/plugins/platforms/minimalegl/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QMinimalEglIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "minimalegl.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "minimalegl.json")
public:
QStringList keys() const;
QPlatformIntegration *create(const QString&, const QStringList&);
diff --git a/src/plugins/platforms/offscreen/main.cpp b/src/plugins/platforms/offscreen/main.cpp
index ca7dc1d18b..f48451d00d 100644
--- a/src/plugins/platforms/offscreen/main.cpp
+++ b/src/plugins/platforms/offscreen/main.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class QOffscreenIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "offscreen.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "offscreen.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro
index 9f10eaad94..5db5e32e65 100644
--- a/src/plugins/platforms/offscreen/offscreen.pro
+++ b/src/plugins/platforms/offscreen/offscreen.pro
@@ -1,6 +1,7 @@
TARGET = qoffscreen
PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QOffscreenIntegrationPlugin
load(qt_plugin)
QT += core-private gui-private platformsupport-private
diff --git a/src/plugins/platforms/openwfd/main.cpp b/src/plugins/platforms/openwfd/main.cpp
index 724c5cfa4b..cea3c50e56 100644
--- a/src/plugins/platforms/openwfd/main.cpp
+++ b/src/plugins/platforms/openwfd/main.cpp
@@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE
class QOpenWFDIntegrationPlugin : public QPlatformIntegrationPlugin
{
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/qnx/main.cpp b/src/plugins/platforms/qnx/main.cpp
index ea50b12cb3..fb81928625 100644
--- a/src/plugins/platforms/qnx/main.cpp
+++ b/src/plugins/platforms/qnx/main.cpp
@@ -46,9 +46,8 @@ QT_BEGIN_NAMESPACE
QPlatformIntegration *QQnxIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- Q_UNUSED(paramList);
if (system.toLower() == QLatin1String("qnx"))
- return new QQnxIntegration;
+ return new QQnxIntegration(paramList);
return 0;
}
diff --git a/src/plugins/platforms/qnx/main.h b/src/plugins/platforms/qnx/main.h
index 0b5f6323c4..683b20efd2 100644
--- a/src/plugins/platforms/qnx/main.h
+++ b/src/plugins/platforms/qnx/main.h
@@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE
class QQnxIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "qnx.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qnx.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 398b64640e..7c497b4434 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -11,11 +11,11 @@ QT += platformsupport-private core-private gui-private
CONFIG(blackberry) {
CONFIG += qqnx_pps
- # Unomment this to enable screen event handling
- # through a dedicated thread.
- # DEFINES += QQNX_SCREENEVENTTHREAD
+ # Uncomment following line to enable screen event
+ # handling through a dedicated thread.
+ # CONFIG += qqnx_screeneventthread
} else {
- DEFINES += QQNX_SCREENEVENTTHREAD
+ CONFIG += qqnx_screeneventthread
}
# Uncomment these to enable debugging output for various aspects of the plugin
@@ -40,11 +40,11 @@ CONFIG(blackberry) {
#DEFINES += QQNXVIRTUALKEYBOARD_DEBUG
#DEFINES += QQNXWINDOW_DEBUG
#DEFINES += QQNXCURSOR_DEBUG
+#DEFINES += QQNXFILEPICKER_DEBUG
SOURCES = main.cpp \
qqnxbuffer.cpp \
- qqnxscreeneventthread.cpp \
qqnxintegration.cpp \
qqnxscreen.cpp \
qqnxwindow.cpp \
@@ -60,7 +60,6 @@ SOURCES = main.cpp \
HEADERS = main.h \
qqnxbuffer.h \
- qqnxscreeneventthread.h \
qqnxkeytranslator.h \
qqnxintegration.h \
qqnxscreen.h \
@@ -75,6 +74,12 @@ HEADERS = main.h \
qqnxservices.h \
qqnxcursor.h
+CONFIG(qqnx_screeneventthread) {
+ DEFINES += QQNX_SCREENEVENTTHREAD
+ SOURCES += qqnxscreeneventthread.cpp
+ HEADERS += qqnxscreeneventthread.h
+}
+
LIBS += -lscreen
contains(QT_CONFIG, opengles2) {
@@ -91,8 +96,7 @@ CONFIG(blackberry) {
qqnxbpseventfilter.cpp \
qqnxvirtualkeyboardbps.cpp \
qqnxtheme.cpp \
- qqnxsystemsettings.cpp \
- qqnxfiledialoghelper.cpp
+ qqnxsystemsettings.cpp
HEADERS += qqnxnavigatorbps.h \
qqnxeventdispatcher_blackberry.h \
@@ -105,6 +109,17 @@ CONFIG(blackberry) {
LIBS += -lbps
}
+CONFIG(blackberry-playbook) {
+ SOURCES += qqnxfiledialoghelper_playbook.cpp
+} else {
+ CONFIG(blackberry) {
+ SOURCES += qqnxfiledialoghelper_bb10.cpp \
+ qqnxfilepicker.cpp
+
+ HEADERS += qqnxfilepicker.h
+ }
+}
+
CONFIG(qqnx_pps) {
DEFINES += QQNX_PPS
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
index e723e32301..4c36a97ab6 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
@@ -41,11 +41,12 @@
#include "qqnxbpseventfilter.h"
#include "qqnxnavigatoreventhandler.h"
-#include "qqnxfiledialoghelper.h"
#include "qqnxscreen.h"
#include "qqnxscreeneventhandler.h"
#include "qqnxvirtualkeyboardbps.h"
+#include "qqnxfiledialoghelper.h"
+#include <QCoreApplication>
#include <QAbstractEventDispatcher>
#include <QDebug>
@@ -126,6 +127,7 @@ void QQnxBpsEventFilter::unregisterForScreenEvents(QQnxScreen *screen)
qWarning("QQNX: failed to unregister for screen events on screen %p", screen->nativeContext());
}
+#if defined(Q_OS_BLACKBERRY_TABLET)
void QQnxBpsEventFilter::registerForDialogEvents(QQnxFileDialogHelper *dialog)
{
if (dialog_request_events(0) != BPS_SUCCESS)
@@ -141,6 +143,7 @@ void QQnxBpsEventFilter::unregisterForDialogEvents(QQnxFileDialogHelper *dialog)
if (count == 0)
qWarning("QQNX: attempting to unregister dialog that was not registered");
}
+#endif // Q_OS_BLACKBERRY_TABLET
bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
@@ -160,12 +163,14 @@ bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *me
return m_screenEventHandler->handleEvent(screenEvent);
}
+#if defined(Q_OS_BLACKBERRY_TABLET)
if (eventDomain == dialog_get_domain()) {
dialog_instance_t nativeDialog = dialog_event_get_dialog_instance(event);
QQnxFileDialogHelper *dialog = m_dialogMapper.value(nativeDialog, 0);
if (dialog)
return dialog->handleEvent(event);
}
+#endif
if (eventDomain == navigator_get_domain())
return handleNavigatorEvent(event);
@@ -249,6 +254,11 @@ bool QQnxBpsEventFilter::handleNavigatorEvent(bps_event_t *event)
break;
}
+ case NAVIGATOR_LOW_MEMORY:
+ qWarning() << "QGuiApplication based process" << QCoreApplication::applicationPid()
+ << "received \"NAVIGATOR_LOW_MEMORY\" event";
+ return false;
+
default:
qBpsEventFilterDebug() << Q_FUNC_INFO << "Unhandled navigator event. code=" << bps_event_get_code(event);
return false;
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.h b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
index e897863efb..f8e36823d5 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.h
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
@@ -73,8 +73,10 @@ public:
void registerForScreenEvents(QQnxScreen *screen);
void unregisterForScreenEvents(QQnxScreen *screen);
+#ifdef Q_OS_BLACKBERRY_TABLET
void registerForDialogEvents(QQnxFileDialogHelper *dialog);
void unregisterForDialogEvents(QQnxFileDialogHelper *dialog);
+#endif
private:
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
index e17ea80501..e7c68f6ff5 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
@@ -44,12 +44,19 @@
#include <qpa/qplatformdialoghelper.h>
-#include <bps/dialog.h>
QT_BEGIN_NAMESPACE
class QQnxIntegration;
+#if defined(Q_OS_BLACKBERRY_TABLET)
+#include <bps/dialog.h>
+#define NativeDialogPtr dialog_instance_t
+#else
+class QQnxFilePicker;
+#define NativeDialogPtr QQnxFilePicker *
+#endif
+
class QQnxFileDialogHelper : public QPlatformFileDialogHelper
{
Q_OBJECT
@@ -57,7 +64,9 @@ public:
explicit QQnxFileDialogHelper(const QQnxIntegration *);
~QQnxFileDialogHelper();
+#if defined(Q_OS_BLACKBERRY_TABLET)
bool handleEvent(bps_event_t *event);
+#endif
void exec();
@@ -65,29 +74,32 @@ public:
void hide();
bool defaultNameFilterDisables() const;
- void setDirectory(const QString &directory);
- QString directory() const;
- void selectFile(const QString &fileName);
- QStringList selectedFiles() const;
+ void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ QUrl directory() const Q_DECL_OVERRIDE;
+ void selectFile(const QUrl &fileName) Q_DECL_OVERRIDE;
+ QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
void setFilter();
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
- dialog_instance_t nativeDialog() const { return m_dialog; }
+ NativeDialogPtr nativeDialog() const { return m_dialog; }
Q_SIGNALS:
void dialogClosed();
private:
void setNameFilter(const QString &filter);
+ void setNameFilters(const QStringList &filters);
const QQnxIntegration *m_integration;
- dialog_instance_t m_dialog;
+ NativeDialogPtr m_dialog;
QFileDialogOptions::AcceptMode m_acceptMode;
QString m_selectedFilter;
QPlatformDialogHelper::DialogCode m_result;
- QStringList m_paths;
+#if defined(Q_OS_BLACKBERRY_TABLET)
+ QList<QUrl> m_paths;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
new file mode 100644
index 0000000000..dc841eb1a9
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
@@ -0,0 +1,217 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqnxfiledialoghelper.h"
+
+#include "qqnxfilepicker.h"
+#include "qqnxbpseventfilter.h"
+#include "qqnxscreen.h"
+#include "qqnxintegration.h"
+
+#include <QDebug>
+#include <QEventLoop>
+#include <QScreen>
+#include <QTimer>
+#include <QWindow>
+
+#ifdef QQNXFILEDIALOGHELPER_DEBUG
+#define qFileDialogHelperDebug qDebug
+#else
+#define qFileDialogHelperDebug QT_NO_QDEBUG_MACRO
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QQnxFileDialogHelper::QQnxFileDialogHelper(const QQnxIntegration *integration)
+ : QPlatformFileDialogHelper(),
+ m_integration(integration),
+ m_dialog(new QQnxFilePicker),
+ m_acceptMode(QFileDialogOptions::AcceptOpen),
+ m_selectedFilter(),
+ m_result(QPlatformDialogHelper::Rejected)
+{
+}
+
+QQnxFileDialogHelper::~QQnxFileDialogHelper()
+{
+ delete m_dialog;
+}
+
+void QQnxFileDialogHelper::exec()
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // Clear any previous results
+ m_dialog->setDirectories(QStringList());
+
+ QEventLoop loop;
+ connect(m_dialog, SIGNAL(closed()), &loop, SLOT(quit()));
+ loop.exec();
+
+ if (m_dialog->selectedFiles().isEmpty())
+ Q_EMIT reject();
+ else
+ Q_EMIT accept();
+}
+
+bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+{
+ Q_UNUSED(flags);
+ Q_UNUSED(parent);
+ Q_UNUSED(modality);
+
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // Create dialog
+ const QSharedPointer<QFileDialogOptions> &opts = options();
+ if (opts->acceptMode() == QFileDialogOptions::AcceptOpen) {
+ // Select one or many files?
+ const QQnxFilePicker::Mode mode = (opts->fileMode() == QFileDialogOptions::ExistingFiles)
+ ? QQnxFilePicker::PickerMultiple : QQnxFilePicker::Picker;
+
+ m_dialog->setMode(mode);
+
+ // Set the actual list of extensions
+ if (!opts->nameFilters().isEmpty())
+ setNameFilters(opts->nameFilters());
+ else
+ setNameFilter(tr("All files (*.*)"));
+ } else {
+ const QQnxFilePicker::Mode mode = (opts->initiallySelectedFiles().count() >= 2)
+ ? QQnxFilePicker::SaverMultiple : QQnxFilePicker::Saver;
+
+ m_dialog->setMode(mode);
+
+ if (!opts->initiallySelectedFiles().isEmpty()) {
+ QStringList files;
+ Q_FOREACH ( const QUrl &url, opts->initiallySelectedFiles() )
+ files.append(url.toLocalFile());
+ m_dialog->setDefaultSaveFileNames(files);
+ }
+ }
+
+ // Cache the accept mode so we know which functions to use to get the results back
+ m_acceptMode = opts->acceptMode();
+ m_dialog->setTitle(opts->windowTitle());
+ m_dialog->open();
+
+ return true;
+}
+
+void QQnxFileDialogHelper::hide()
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ m_dialog->close();
+}
+
+bool QQnxFileDialogHelper::defaultNameFilterDisables() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return false;
+}
+
+void QQnxFileDialogHelper::setDirectory(const QUrl &directory)
+{
+ m_dialog->addDirectory(directory.toLocalFile());
+}
+
+QUrl QQnxFileDialogHelper::directory() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ if (!m_dialog->directories().isEmpty())
+ return QUrl::fromLocalFile(m_dialog->directories().first());
+
+ return QUrl();
+}
+
+void QQnxFileDialogHelper::selectFile(const QUrl &fileName)
+{
+ m_dialog->addDefaultSaveFileName(fileName.toLocalFile());
+}
+
+QList<QUrl> QQnxFileDialogHelper::selectedFiles() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ QList<QUrl> urls;
+ QStringList files = m_dialog->selectedFiles();
+ Q_FOREACH (const QString &file, files)
+ urls.append(QUrl::fromLocalFile(file));
+ return urls;
+}
+
+void QQnxFileDialogHelper::setFilter()
+{
+ // No native api to support setting a filter from QDir::Filters
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+}
+
+void QQnxFileDialogHelper::selectNameFilter(const QString &filter)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+ setNameFilter(filter);
+}
+
+QString QQnxFileDialogHelper::selectedNameFilter() const
+{
+ // For now there is no way for the user to change the selected filter
+ // so this just reflects what the developer has set programmatically.
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return m_selectedFilter;
+}
+
+void QQnxFileDialogHelper::setNameFilter(const QString &filter)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+
+ setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
+}
+
+void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filters =" << filters;
+
+ Q_ASSERT(!filters.isEmpty());
+
+ m_dialog->setFilters(filters);
+ m_selectedFilter = filters.first();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
index 0325a33268..2a743d03f7 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
@@ -102,7 +102,7 @@ bool QQnxFileDialogHelper::handleEvent(bps_event_t *event)
for (int i = 0; i < pathCount; ++i) {
QString path = QFile::decodeName(filePaths[i]);
- m_paths.append(path);
+ m_paths.append(QUrl::fromLocalFile(path));
qFileDialogHelperDebug() << "path =" << path;
}
@@ -112,13 +112,13 @@ bool QQnxFileDialogHelper::handleEvent(bps_event_t *event)
const char *filePath = dialog_event_get_filesave_filepath(event);
QString path = QFile::decodeName(filePath);
qFileDialogHelperDebug() << "path =" << path;
- m_paths.append(path);
+ m_paths.append(QUrl::fromLocalFile(path));
}
} else { // Cancel
m_result = QPlatformDialogHelper::Rejected;
}
- emit dialogClosed();
+ Q_EMIT dialogClosed();
return true;
}
@@ -135,9 +135,9 @@ void QQnxFileDialogHelper::exec()
loop.exec();
if (m_result == QPlatformDialogHelper::Accepted)
- emit accept();
+ Q_EMIT accept();
else
- emit reject();
+ Q_EMIT reject();
}
bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
@@ -188,7 +188,7 @@ bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modali
// Maybe pre-select a filename
if (!opts->initiallySelectedFiles().isEmpty()) {
- QString fileName = opts->initiallySelectedFiles().first();
+ QString fileName = opts->initiallySelectedFiles().first().toLocalFile();
dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
}
@@ -240,29 +240,29 @@ bool QQnxFileDialogHelper::defaultNameFilterDisables() const
return false;
}
-void QQnxFileDialogHelper::setDirectory(const QString &directory)
+void QQnxFileDialogHelper::setDirectory(const QUrl &directory)
{
qFileDialogHelperDebug() << Q_FUNC_INFO << "directory =" << directory;
// No native API for setting the directory(!). The best we can do is to
// set it as the file name but even then only with a file save dialog.
if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
- dialog_set_filesave_filename(m_dialog, QFile::encodeName(directory).constData());
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(directory.toLocalFile()).constData());
}
-QString QQnxFileDialogHelper::directory() const
+QUrl QQnxFileDialogHelper::directory() const
{
qFileDialogHelperDebug() << Q_FUNC_INFO;
return m_paths.first();
}
-void QQnxFileDialogHelper::selectFile(const QString &fileName)
+void QQnxFileDialogHelper::selectFile(const QUrl &fileName)
{
qFileDialogHelperDebug() << Q_FUNC_INFO << "filename =" << fileName;
if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
- dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName.toLocalFile()).constData());
}
-QStringList QQnxFileDialogHelper::selectedFiles() const
+QList<QUrl> QQnxFileDialogHelper::selectedFiles() const
{
qFileDialogHelperDebug() << Q_FUNC_INFO;
return m_paths;
@@ -291,9 +291,15 @@ QString QQnxFileDialogHelper::selectedNameFilter() const
void QQnxFileDialogHelper::setNameFilter(const QString &filter)
{
qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+ setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
+}
+
+void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filters =" << filters;
+
+ Q_ASSERT(!filters.isEmpty());
- // Extract the globbing expressions
- QStringList filters = QPlatformFileDialogHelper::cleanFilterList(filter);
char **globs = new char*[filters.size()];
for (int i = 0; i < filters.size(); ++i) {
QByteArray glob = filters.at(i).toLocal8Bit();
@@ -303,7 +309,7 @@ void QQnxFileDialogHelper::setNameFilter(const QString &filter)
// Set the filters
dialog_set_filebrowse_filter(m_dialog, const_cast<const char**>(globs), filters.size());
- m_selectedFilter = filter;
+ m_selectedFilter = filters.first();
// Cleanup
for (int i = 0; i < filters.size(); ++i)
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
new file mode 100644
index 0000000000..5229d1f1f5
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
@@ -0,0 +1,289 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqnxfilepicker.h"
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QDebug>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonParseError>
+#include <QUrl>
+
+#include <bps/navigator.h>
+#include <bps/navigator_invoke.h>
+
+#include <errno.h>
+
+#ifdef QQNXFILEPICKER_DEBUG
+#define qFilePickerDebug qDebug
+#else
+#define qFilePickerDebug QT_NO_QDEBUG_MACRO
+#endif
+
+static const char s_filePickerTarget[] = "sys.filepicker.target";
+
+QQnxFilePicker::QQnxFilePicker(QObject *parent)
+ : QObject(parent)
+ , m_invocationHandle(0)
+ , m_mode(QQnxFilePicker::Picker)
+ , m_title(tr("Pick a file"))
+{
+ QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
+}
+
+QQnxFilePicker::~QQnxFilePicker()
+{
+ cleanup();
+
+ QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
+}
+
+void QQnxFilePicker::open()
+{
+ if (m_invocationHandle)
+ return;
+
+ int errorCode = BPS_SUCCESS;
+
+ errorCode = navigator_invoke_invocation_create(&m_invocationHandle);
+ if (errorCode != BPS_SUCCESS) {
+ qWarning() << "QQnxFilePicker: unable to create invocation:" << strerror(errno);
+ return;
+ }
+
+ errorCode = navigator_invoke_invocation_set_target(m_invocationHandle, s_filePickerTarget);
+
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set target:" << strerror(errno);
+ return;
+ }
+
+ errorCode = navigator_invoke_invocation_set_action(m_invocationHandle, "bb.action.OPEN");
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set action:" << strerror(errno);
+ return;
+ }
+
+ errorCode = navigator_invoke_invocation_set_type(m_invocationHandle, "application/vnd.blackberry.file_picker");
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set mime type:" << strerror(errno);
+ return;
+ }
+
+ QVariantMap map;
+ map[QStringLiteral("Type")] = QStringLiteral("Other");
+ map[QStringLiteral("Mode")] = modeToString(m_mode);
+ map[QStringLiteral("Title")] = m_title;
+ map[QStringLiteral("ViewMode")] = QStringLiteral("Default");
+ map[QStringLiteral("SortBy")] = QStringLiteral("Default");
+ map[QStringLiteral("SortOrder")] = QStringLiteral("Default");
+ map[QStringLiteral("ImageCrop")] = false;
+ map[QStringLiteral("AllowOverwrite")] = false;
+
+ if (!m_defaultSaveFileNames.isEmpty())
+ map[QStringLiteral("DefaultFileNames")] = m_defaultSaveFileNames.join(",");
+ if (!m_filters.isEmpty())
+ map[QStringLiteral("Filter")] = m_filters.join(";");
+
+ QJsonDocument document;
+ document.setObject(QJsonObject::fromVariantMap(map));
+ const QByteArray jsonData = document.toJson(QJsonDocument::Compact);
+
+ errorCode = navigator_invoke_invocation_set_data(m_invocationHandle, jsonData.constData(), jsonData.size());
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set data:" << strerror(errno);
+ return;
+ }
+
+ navigator_invoke_invocation_send(m_invocationHandle);
+}
+
+void QQnxFilePicker::close()
+{
+ navigator_card_close_child();
+ cleanup();
+}
+
+bool QQnxFilePicker::nativeEventFilter(const QByteArray&, void *message, long*)
+{
+ bps_event_t * const event = static_cast<bps_event_t*>(message);
+ if (!event)
+ return false;
+
+ if (bps_event_get_code(event) == NAVIGATOR_INVOKE_TARGET_RESULT) {
+ const char *id = navigator_event_get_id(event);
+ const char *err = navigator_event_get_err(event);
+ qFilePickerDebug("received invocation response: id=%s err=%s", id, err);
+ } else if (bps_event_get_code(event) == NAVIGATOR_CHILD_CARD_CLOSED) {
+ const char *data = navigator_event_get_card_closed_data(event);
+ qFilePickerDebug("received data: data='%s'", data);
+ handleFilePickerResponse(data);
+ }
+
+ return false; // do not drop the event
+}
+
+void QQnxFilePicker::setMode(QQnxFilePicker::Mode mode)
+{
+ m_mode = mode;
+}
+
+void QQnxFilePicker::setDefaultSaveFileNames(const QStringList &fileNames)
+{
+ m_defaultSaveFileNames = fileNames;
+}
+
+void QQnxFilePicker::addDefaultSaveFileName(const QString &fileName)
+{
+ m_defaultSaveFileNames.append(fileName);
+}
+
+void QQnxFilePicker::setDirectories(const QStringList &directories)
+{
+ m_directories = directories;
+}
+
+void QQnxFilePicker::addDirectory(const QString &directory)
+{
+ m_directories.append(directory);
+}
+
+void QQnxFilePicker::setFilters(const QStringList &filters)
+{
+ m_filters = filters;
+}
+
+void QQnxFilePicker::setTitle(const QString &title)
+{
+ m_title = title;
+}
+
+QQnxFilePicker::Mode QQnxFilePicker::mode() const
+{
+ return m_mode;
+}
+
+QStringList QQnxFilePicker::defaultSaveFileNames() const
+{
+ return m_defaultSaveFileNames;
+}
+
+QStringList QQnxFilePicker::directories() const
+{
+ return m_directories;
+}
+
+QStringList QQnxFilePicker::filters() const
+{
+ return m_filters;
+}
+
+QStringList QQnxFilePicker::selectedFiles() const
+{
+ return m_selectedFiles;
+}
+
+QString QQnxFilePicker::title() const
+{
+ return m_title;
+}
+
+void QQnxFilePicker::cleanup()
+{
+ if (m_invocationHandle) {
+ navigator_invoke_invocation_destroy(m_invocationHandle);
+ m_invocationHandle = 0;
+ }
+}
+
+void QQnxFilePicker::handleFilePickerResponse(const char *data)
+{
+ QJsonParseError jsonError;
+ QJsonDocument document = QJsonDocument::fromJson(data, &jsonError);
+
+ if (jsonError.error != QJsonParseError::NoError) {
+ qFilePickerDebug() << "Error parsing FilePicker response: "
+ << jsonError.errorString();
+ Q_EMIT closed();
+ cleanup();
+ return;
+ }
+
+ // The response is a list of Json objects.
+ const QVariantList array = document.array().toVariantList();
+
+ foreach (const QVariant &variant, array) {
+ const QJsonObject object = QJsonObject::fromVariantMap(variant.toMap());
+ const QUrl url(object.value(QStringLiteral("uri")).toString());
+ const QString localFile = url.toLocalFile(); // strip "file://"
+
+ if (!localFile.isEmpty())
+ m_selectedFiles << localFile;
+
+ qFilePickerDebug() << "FilePicker uri response:" << localFile;
+ }
+
+ Q_EMIT closed();
+ cleanup();
+}
+
+QString QQnxFilePicker::modeToString(QQnxFilePicker::Mode mode) const
+{
+ switch (mode) {
+ case Picker:
+ return QStringLiteral("Picker");
+ case Saver:
+ return QStringLiteral("Saver");
+ case PickerMultiple:
+ return QStringLiteral("PickerMultiple");
+ case SaverMultiple:
+ return QStringLiteral("SaverMultiple");
+ }
+
+ return QStringLiteral("Picker");
+}
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.h b/src/plugins/platforms/qnx/qqnxfilepicker.h
new file mode 100644
index 0000000000..5bb8f0969f
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfilepicker.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQNXFILEPICKER_H
+#define QQNXFILEPICKER_H
+
+#include <QAbstractNativeEventFilter>
+#include <QObject>
+#include <QStringList>
+
+struct navigator_invoke_invocation_t;
+
+class QQnxFilePicker : public QObject, public QAbstractNativeEventFilter
+{
+ Q_OBJECT
+
+public:
+ explicit QQnxFilePicker(QObject *parent = 0);
+ ~QQnxFilePicker();
+
+ enum Mode {
+ Picker,
+ Saver,
+ PickerMultiple,
+ SaverMultiple
+ };
+
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
+ void setMode(Mode mode);
+ void setDefaultSaveFileNames(const QStringList &fileNames);
+ void addDefaultSaveFileName(const QString &fileName);
+ void setDirectories(const QStringList &directories);
+ void addDirectory(const QString &directory);
+ void setFilters(const QStringList &filters);
+ void setTitle(const QString &title);
+
+ Mode mode() const;
+
+ QStringList defaultSaveFileNames() const;
+ QStringList directories() const;
+ QStringList filters() const;
+ QStringList selectedFiles() const;
+
+ QString title() const;
+
+Q_SIGNALS:
+ void closed();
+
+public Q_SLOTS:
+ void open();
+ void close();
+
+private:
+ void cleanup();
+ void handleFilePickerResponse(const char *data);
+
+ QString modeToString(Mode mode) const;
+
+ navigator_invoke_invocation_t *m_invocationHandle;
+
+ Mode m_mode;
+
+ QStringList m_defaultSaveFileNames;
+ QStringList m_directories;
+ QStringList m_filters;
+ QStringList m_selectedFiles;
+
+ QString m_title;
+};
+
+#endif // QQNXFILEPICKER_H
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index ed959467ff..448509c69d 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -60,36 +60,10 @@ QT_BEGIN_NAMESPACE
EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY;
-static EGLenum checkEGLError(const char *msg)
-{
- static const char *errmsg[] =
- {
- "EGL function succeeded",
- "EGL is not initialized, or could not be initialized, for the specified display",
- "EGL cannot access a requested resource",
- "EGL failed to allocate resources for the requested operation",
- "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
- "EGLConfig argument does not name a valid EGLConfig",
- "EGLContext argument does not name a valid EGLContext",
- "EGL current surface of the calling thread is no longer valid",
- "EGLDisplay argument does not name a valid EGLDisplay",
- "EGL arguments are inconsistent",
- "EGLNativePixmapType argument does not refer to a valid native pixmap",
- "EGLNativeWindowType argument does not refer to a valid native window",
- "EGL one or more argument values are invalid",
- "EGLSurface argument does not name a valid surface configured for rendering",
- "EGL power management event has occurred",
- };
- EGLenum error = eglGetError();
- fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
- return error;
-}
-
QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
: QPlatformOpenGLContext(),
m_glContext(glContext),
- m_eglSurface(EGL_NO_SURFACE),
- m_newSurfaceRequested(true) // Create a surface the first time makeCurrent() is called
+ m_currentEglSurface(EGL_NO_SURFACE)
{
qGLContextDebug() << Q_FUNC_INFO;
QSurfaceFormat format = m_glContext->format();
@@ -168,9 +142,31 @@ QQnxGLContext::~QQnxGLContext()
// Cleanup EGL context if it exists
if (m_eglContext != EGL_NO_CONTEXT)
eglDestroyContext(ms_eglDisplay, m_eglContext);
+}
- // Cleanup EGL surface if it exists
- destroySurface();
+EGLenum QQnxGLContext::checkEGLError(const char *msg)
+{
+ static const char *errmsg[] =
+ {
+ "EGL function succeeded",
+ "EGL is not initialized, or could not be initialized, for the specified display",
+ "EGL cannot access a requested resource",
+ "EGL failed to allocate resources for the requested operation",
+ "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
+ "EGLConfig argument does not name a valid EGLConfig",
+ "EGLContext argument does not name a valid EGLContext",
+ "EGL current surface of the calling thread is no longer valid",
+ "EGLDisplay argument does not name a valid EGLDisplay",
+ "EGL arguments are inconsistent",
+ "EGLNativePixmapType argument does not refer to a valid native pixmap",
+ "EGLNativeWindowType argument does not refer to a valid native window",
+ "EGL one or more argument values are invalid",
+ "EGLSurface argument does not name a valid surface configured for rendering",
+ "EGL power management event has occurred",
+ };
+ EGLenum error = eglGetError();
+ fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
+ return error;
}
void QQnxGLContext::initialize()
@@ -199,12 +195,6 @@ void QQnxGLContext::shutdown()
eglTerminate(ms_eglDisplay);
}
-void QQnxGLContext::requestSurfaceChange()
-{
- qGLContextDebug() << Q_FUNC_INFO;
- m_newSurfaceRequested.testAndSetRelease(false, true);
-}
-
bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
{
qGLContextDebug() << Q_FUNC_INFO;
@@ -216,14 +206,18 @@ bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
if (eglResult != EGL_TRUE)
qFatal("QQnxGLContext: failed to set EGL API, err=%d", eglGetError());
- if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
- qGLContextDebug() << "New EGL surface requested";
+ QQnxWindow *platformWindow = dynamic_cast<QQnxWindow*>(surface);
+ if (!platformWindow)
+ return false;
+
+ platformWindow->setPlatformOpenGLContext(this);
+
+ if (m_currentEglSurface == EGL_NO_SURFACE || m_currentEglSurface != platformWindow->getSurface()) {
+ m_currentEglSurface = platformWindow->getSurface();
doneCurrent();
- destroySurface();
- createSurface(surface);
}
- eglResult = eglMakeCurrent(ms_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
+ eglResult = eglMakeCurrent(ms_eglDisplay, m_currentEglSurface, m_currentEglSurface, m_eglContext);
if (eglResult != EGL_TRUE) {
checkEGLError("eglMakeCurrent");
qFatal("QQNX: failed to set current EGL context, err=%d", eglGetError());
@@ -248,18 +242,12 @@ void QQnxGLContext::doneCurrent()
void QQnxGLContext::swapBuffers(QPlatformSurface *surface)
{
- Q_UNUSED(surface);
qGLContextDebug() << Q_FUNC_INFO;
+ QQnxWindow *platformWindow = dynamic_cast<QQnxWindow*>(surface);
+ if (!platformWindow)
+ return;
- // Set current rendering API
- EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (eglResult != EGL_TRUE)
- qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
-
- // Post EGL surface to window
- eglResult = eglSwapBuffers(ms_eglDisplay, m_eglSurface);
- if (eglResult != EGL_TRUE)
- qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError());
+ platformWindow->swapEGLBuffers();
}
QFunctionPointer QQnxGLContext::getProcAddress(const QByteArray &procName)
@@ -275,6 +263,10 @@ QFunctionPointer QQnxGLContext::getProcAddress(const QByteArray &procName)
return static_cast<QFunctionPointer>(eglGetProcAddress(procName.constData()));
}
+EGLDisplay QQnxGLContext::getEglDisplay() {
+ return ms_eglDisplay;
+}
+
EGLint *QQnxGLContext::contextAttrs()
{
qGLContextDebug() << Q_FUNC_INFO;
@@ -288,66 +280,4 @@ EGLint *QQnxGLContext::contextAttrs()
#endif
}
-bool QQnxGLContext::isCurrent() const
-{
- qGLContextDebug() << Q_FUNC_INFO;
- return (eglGetCurrentContext() == m_eglContext);
-}
-
-void QQnxGLContext::createSurface(QPlatformSurface *surface)
-{
- qGLContextDebug() << Q_FUNC_INFO;
-
- // Get a pointer to the corresponding platform window
- QQnxWindow *platformWindow = dynamic_cast<QQnxWindow*>(surface);
- if (!platformWindow)
- qFatal("QQNX: unable to create EGLSurface without a QQnxWindow");
-
- // Link the window and context
- platformWindow->setPlatformOpenGLContext(this);
-
- // Fetch the surface size from the window and update
- // the window's buffers before we create the EGL surface
- const QSize surfaceSize = platformWindow->requestedBufferSize();
- if (!surfaceSize.isValid()) {
- qFatal("QQNX: Trying to create 0 size EGL surface. "
- "Please set a valid window size before calling QOpenGLContext::makeCurrent()");
- }
- platformWindow->setBufferSize(surfaceSize);
-
- // Post root window, in case it hasn't been posted yet, to make it appear.
- platformWindow->screen()->onWindowPost(platformWindow);
-
- // Obtain the native handle for our window
- screen_window_t handle = platformWindow->nativeHandle();
-
- const EGLint eglSurfaceAttrs[] =
- {
- EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
- EGL_NONE
- };
-
- // Create EGL surface
- m_eglSurface = eglCreateWindowSurface(ms_eglDisplay, m_eglConfig, (EGLNativeWindowType) handle, eglSurfaceAttrs);
- if (m_eglSurface == EGL_NO_SURFACE) {
- checkEGLError("eglCreateWindowSurface");
- qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError());
- }
-}
-
-void QQnxGLContext::destroySurface()
-{
- qGLContextDebug() << Q_FUNC_INFO;
-
- // Destroy EGL surface if it exists
- if (m_eglSurface != EGL_NO_SURFACE) {
- EGLBoolean eglResult = eglDestroySurface(ms_eglDisplay, m_eglSurface);
- if (eglResult != EGL_TRUE) {
- qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
- }
- }
-
- m_eglSurface = EGL_NO_SURFACE;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h
index 6a7fca7df2..ff57861498 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.h
+++ b/src/plugins/platforms/qnx/qqnxglcontext.h
@@ -59,6 +59,8 @@ public:
QQnxGLContext(QOpenGLContext *glContext);
virtual ~QQnxGLContext();
+ static EGLenum checkEGLError(const char *msg);
+
static void initialize();
static void shutdown();
@@ -71,13 +73,10 @@ public:
virtual QSurfaceFormat format() const { return m_windowFormat; }
- bool isCurrent() const;
-
- void createSurface(QPlatformSurface *surface);
- void destroySurface();
-
+ static EGLDisplay getEglDisplay();
+ EGLConfig getEglConfig() const { return m_eglConfig;}
private:
- /** \todo Should this be non-static so we can use additional displays? */
+ //Can be static because different displays returne the same handle
static EGLDisplay ms_eglDisplay;
QSurfaceFormat m_windowFormat;
@@ -85,9 +84,7 @@ private:
EGLConfig m_eglConfig;
EGLContext m_eglContext;
- EGLSurface m_eglSurface;
-
- QAtomicInt m_newSurfaceRequested;
+ EGLSurface m_currentEglSurface;
static EGLint *contextAttrs();
};
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index feb05e3093..fa9961ccce 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -40,7 +40,9 @@
****************************************************************************/
#include "qqnxintegration.h"
+#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
+#endif
#include "qqnxnativeinterface.h"
#include "qqnxrasterbackingstore.h"
#include "qqnxscreen.h"
@@ -84,6 +86,8 @@
#include <qpa/qplatformwindow.h>
#include <qpa/qwindowsysteminterface.h>
+#include <QtGui/private/qguiapplication_p.h>
+
#if !defined(QT_NO_OPENGL)
#include "qqnxglcontext.h"
#include <QtGui/QOpenGLContext>
@@ -107,9 +111,20 @@ QT_BEGIN_NAMESPACE
QQnxWindowMapper QQnxIntegration::ms_windowMapper;
QMutex QQnxIntegration::ms_windowMapperMutex;
-QQnxIntegration::QQnxIntegration()
+static inline QQnxIntegration::Options parseOptions(const QStringList &paramList)
+{
+ QQnxIntegration::Options options = QQnxIntegration::NoOptions;
+ if (!paramList.contains(QLatin1String("no-fullscreen"))) {
+ options |= QQnxIntegration::FullScreenApplication;
+ }
+ return options;
+}
+
+QQnxIntegration::QQnxIntegration(const QStringList &paramList)
: QPlatformIntegration()
+#if defined(QQNX_SCREENEVENTTHREAD)
, m_screenEventThread(0)
+#endif
, m_navigatorEventHandler(new QQnxNavigatorEventHandler())
, m_virtualKeyboard(0)
#if defined(QQNX_PPS)
@@ -134,6 +149,7 @@ QQnxIntegration::QQnxIntegration()
#if !defined(QT_NO_DRAGANDDROP)
, m_drag(new QSimpleDrag())
#endif
+ , m_options(parseOptions(paramList))
{
qIntegrationDebug() << Q_FUNC_INFO;
// Open connection to QNX composition manager
@@ -185,8 +201,13 @@ QQnxIntegration::QQnxIntegration()
#if defined(Q_OS_BLACKBERRY)
QQnxVirtualKeyboardBps* virtualKeyboardBps = new QQnxVirtualKeyboardBps;
- m_bpsEventFilter = new QQnxBpsEventFilter(m_navigatorEventHandler,
- (m_screenEventThread ? 0 : m_screenEventHandler), virtualKeyboardBps);
+
+#if defined(QQNX_SCREENEVENTTHREAD)
+ m_bpsEventFilter = new QQnxBpsEventFilter(m_navigatorEventHandler, 0, virtualKeyboardBps);
+#else
+ m_bpsEventFilter = new QQnxBpsEventFilter(m_navigatorEventHandler, m_screenEventHandler, virtualKeyboardBps);
+#endif
+
m_bpsEventFilter->installOnEventDispatcher(m_eventDispatcher);
m_virtualKeyboard = virtualKeyboardBps;
@@ -383,7 +404,7 @@ QPlatformDrag *QQnxIntegration::drag() const
QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
qIntegrationDebug() << Q_FUNC_INFO;
- if (hint == ShowIsFullScreen)
+ if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
return true;
return QPlatformIntegration::styleHint(hint);
@@ -526,6 +547,11 @@ QQnxScreen *QQnxIntegration::primaryDisplay() const
return m_screens.first();
}
+QQnxIntegration::Options QQnxIntegration::options() const
+{
+ return m_options;
+}
+
bool QQnxIntegration::supportsNavigatorEvents() const
{
// If QQNX_PPS or Q_OS_BLACKBERRY is defined then we have navigator
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index e3eb9e06ba..dd8973b767 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -51,7 +51,9 @@
QT_BEGIN_NAMESPACE
class QQnxBpsEventFilter;
+#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
+#endif
class QQnxFileDialogHelper;
class QQnxNativeInterface;
class QQnxWindow;
@@ -80,7 +82,12 @@ typedef QHash<screen_window_t, QWindow *> QQnxWindowMapper;
class QQnxIntegration : public QPlatformIntegration
{
public:
- QQnxIntegration();
+ enum Option { // Options to be passed on command line.
+ NoOptions = 0x0,
+ FullScreenApplication = 0x1
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+ explicit QQnxIntegration(const QStringList &paramList);
~QQnxIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
@@ -129,6 +136,8 @@ public:
void createDisplay(screen_display_t display, bool isPrimary);
void removeDisplay(QQnxScreen *screen);
QQnxScreen *primaryDisplay() const;
+ Options options() const;
+
private:
void createDisplays();
void destroyDisplays();
@@ -137,7 +146,9 @@ private:
static void removeWindow(screen_window_t qnxWindow);
screen_context_t m_screenContext;
+#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_screenEventThread;
+#endif
QQnxNavigatorEventHandler *m_navigatorEventHandler;
QQnxAbstractVirtualKeyboard *m_virtualKeyboard;
#if defined(QQNX_PPS)
@@ -164,6 +175,8 @@ private:
static QQnxWindowMapper ms_windowMapper;
static QMutex ms_windowMapperMutex;
+ const Options m_options;
+
friend class QQnxWindow;
};
diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
index 6a7a4d0944..1da3cd5446 100644
--- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
@@ -91,6 +91,11 @@ void QQnxRasterBackingStore::flush(QWindow *window, const QRegion &region, const
if (window)
targetWindow = static_cast<QQnxWindow *>(window->handle());
+ // we only need to flush the platformWindow backing store, since this is
+ // the buffer where all drawing operations of all windows, including the
+ // child windows, are performed; conceptually ,child windows have no buffers
+ // (actually they do have a 1x1 placeholder buffer due to libscreen limitations),
+ // since Qt will only draw to the backing store of the top-level window.
QQnxWindow *platformWindow = this->platformWindow();
if (!targetWindow || targetWindow == platformWindow) {
@@ -108,28 +113,6 @@ void QQnxRasterBackingStore::flush(QWindow *window, const QRegion &region, const
// update the display with newly rendered content
platformWindow->post(region);
- } else if (targetWindow) {
-
- // The contents of the backing store should be flushed to a different window than the
- // window which owns the buffer.
- // This typically happens for child windows, since child windows share a backing store with
- // their top-level window (TLW).
- // Simply copy the buffer over to the child window, to emulate a painting operation, and
- // then post the window.
- //
- // ### Note that because of the design in the QNX QPA plugin, each window has its own buffers,
- // even though they might share a backing store. This is unneeded overhead, but I don't think
- // libscreen allows to have windows without buffers, or does it?
-
- // We assume that the TLW has been flushed previously and that no changes were made to the
- // backing store inbetween (### does Qt guarantee this?)
-
- targetWindow->adjustBufferSize();
- targetWindow->blitFrom(platformWindow, offset, region);
- targetWindow->post(region);
-
- } else {
- qWarning() << Q_FUNC_INFO << "flush() called without a valid window!";
}
m_hasUnflushedPaintOperations = false;
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 84721c9c2a..7959617443 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -85,7 +85,9 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
if (val[0] > 0 && val[1] > 0)
return QSize(val[0], val[1]);
- qWarning("QQnxScreen: screen_get_display_property_iv() reported an invalid physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE environment variable.", val[0], val[1]);
+ qScreenDebug("QQnxScreen: screen_get_display_property_iv() reported an invalid "
+ "physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE "
+ "environment variable.", val[0], val[1]);
const QString envPhySizeStr = qgetenv("QQNX_PHYSICAL_SCREEN_SIZE");
if (!envPhySizeStr.isEmpty()) {
@@ -94,7 +96,9 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
const int envHeight = envPhySizeStrList.size() == 2 ? envPhySizeStrList[1].toInt() : -1;
if (envWidth <= 0 || envHeight <= 0) {
- qFatal("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format \"width,height\" in mm, with width, height > 0. Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");
+ qFatal("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format "
+ "\"width,height\" in mm, with width, height > 0. "
+ "Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");
return QSize(150, 90);
}
@@ -103,11 +107,14 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
#if defined(QQNX_PHYSICAL_SCREEN_SIZE_DEFINED)
const QSize defSize(QQNX_PHYSICAL_SCREEN_WIDTH, QQNX_PHYSICAL_SCREEN_HEIGHT);
- qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Falling back to defines QQNX_PHYSICAL_SCREEN_WIDTH/QQNX_PHYSICAL_SCREEN_HEIGHT (%dx%d)", defSize.width(), defSize.height());
+ qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Falling back to defines "
+ "QQNX_PHYSICAL_SCREEN_WIDTH/QQNX_PHYSICAL_SCREEN_HEIGHT (%dx%d)",
+ defSize.width(), defSize.height());
return defSize;
#else
if (primaryScreen)
- qFatal("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Could not determine physical screen size.");
+ qFatal("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. "
+ "Could not determine physical screen size.");
return QSize(150, 90);
#endif
}
@@ -119,7 +126,6 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
m_posted(false),
m_keyboardHeight(0),
m_nativeOrientation(Qt::PrimaryOrientation),
- m_platformContext(0),
m_cursor(new QQnxCursor())
{
qScreenDebug() << Q_FUNC_INFO;
@@ -475,9 +481,14 @@ void QQnxScreen::updateHierarchy()
int topZorder;
errno = 0;
- result = screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder);
- if (result != 0)
- qFatal("QQnxScreen: failed to query root window z-order, errno=%d", errno);
+ if (isPrimaryScreen()) {
+ result = screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder);
+ if (result != 0)
+ qFatal("QQnxScreen: failed to query root window z-order, errno=%d", errno);
+ } else {
+ topZorder = 0; //We do not need z ordering on the secondary screen, because only one window
+ //is supported there
+ }
topZorder++; // root window has the lowest z-order in the windowgroup
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index 6e8c2c6a60..e498d27c14 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -133,7 +133,6 @@ private:
Qt::ScreenOrientation m_nativeOrientation;
QRect m_initialGeometry;
QRect m_currentGeometry;
- QPlatformOpenGLContext *m_platformContext;
QList<QQnxWindow *> m_childWindows;
QList<screen_window_t> m_overlays;
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index c2d0e3e41c..c869d29c99 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -469,8 +469,14 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event)
qScreenEventDebug() << Q_FUNC_INFO << "display attachment is now:" << isAttached;
QQnxScreen *screen = m_qnxIntegration->screenForNative(nativeDisplay);
+
if (!screen) {
if (isAttached) {
+ int val[2];
+ screen_get_display_property_iv(nativeDisplay, SCREEN_PROPERTY_SIZE, val);
+ if (val[0] == 0 && val[1] == 0) //If screen size is invalid, wait for the next event
+ return;
+
qScreenEventDebug() << "creating new QQnxScreen for newly attached display";
m_qnxIntegration->createDisplay(nativeDisplay, false /* not primary, we assume */);
}
diff --git a/src/plugins/platforms/qnx/qqnxtheme.cpp b/src/plugins/platforms/qnx/qqnxtheme.cpp
index 733b7223b6..37c1079441 100644
--- a/src/plugins/platforms/qnx/qqnxtheme.cpp
+++ b/src/plugins/platforms/qnx/qqnxtheme.cpp
@@ -58,10 +58,8 @@ QQnxTheme::~QQnxTheme()
bool QQnxTheme::usePlatformNativeDialog(DialogType type) const
{
-#if defined(Q_OS_BLACKBERRY_TABLET)
if (type == QPlatformTheme::FileDialog)
return true;
-#endif
#if !defined(QT_NO_COLORDIALOG)
if (type == QPlatformTheme::ColorDialog)
return false;
@@ -76,10 +74,8 @@ bool QQnxTheme::usePlatformNativeDialog(DialogType type) const
QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) const
{
switch (type) {
-#if defined(Q_OS_BLACKBERRY_TABLET)
case QPlatformTheme::FileDialog:
return new QQnxFileDialogHelper(m_integration);
-#endif
#if !defined(QT_NO_COLORDIALOG)
case QPlatformTheme::ColorDialog:
#endif
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index fb8e8075ad..9b9576c88b 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -72,13 +72,15 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
m_window(0),
m_currentBufferIndex(-1),
m_previousBufferIndex(-1),
-#if !defined(QT_NO_OPENGL)
- m_platformOpenGLContext(0),
-#endif
m_screen(0),
m_parentWindow(0),
m_visible(false),
m_windowState(Qt::WindowNoState),
+#if !defined(QT_NO_OPENGL)
+ m_platformOpenGLContext(0),
+ m_newSurfaceRequested(true),
+ m_eglSurface(EGL_NO_SURFACE),
+#endif
m_requestedBufferSize(window->geometry().size())
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
@@ -86,7 +88,11 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
// Create child QNX window
errno = 0;
- result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ if (static_cast<QQnxScreen *>(window->screen()->handle())->isPrimaryScreen()) {
+ result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ } else {
+ result = screen_create_window(&m_window, m_screenContext);
+ }
if (result != 0)
qFatal("QQnxWindow: failed to create window, errno=%d", errno);
@@ -172,6 +178,11 @@ QQnxWindow::~QQnxWindow()
// Cleanup QNX window and its buffers
screen_destroy_window(m_window);
+
+#if !defined(QT_NO_OPENGL)
+ // Cleanup EGL surface if it exists
+ destroyEGLSurface();
+#endif
}
void QQnxWindow::setGeometry(const QRect &rect)
@@ -180,16 +191,16 @@ void QQnxWindow::setGeometry(const QRect &rect)
#if !defined(QT_NO_OPENGL)
// If this is an OpenGL window we need to request that the GL context updates
- // the EGLsurface on which it is rendering. The surface will be recreated the
- // next time QQnxGLContext::makeCurrent() is called.
+ // the EGLsurface on which it is rendering.
{
// We want the setting of the atomic bool in the GL context to be atomic with
// setting m_requestedBufferSize and therefore extended the scope to include
// that test.
const QMutexLocker locker(&m_mutex);
m_requestedBufferSize = rect.size();
- if (m_platformOpenGLContext != 0 && bufferSize() != rect.size())
- m_platformOpenGLContext->requestSurfaceChange();
+ if (m_platformOpenGLContext != 0 && bufferSize() != rect.size()) {
+ m_newSurfaceRequested.testAndSetRelease(false, true);
+ }
}
#endif
@@ -336,6 +347,9 @@ QSize QQnxWindow::requestedBufferSize() const
void QQnxWindow::adjustBufferSize()
{
+ if (m_parentWindow)
+ return;
+
const QSize windowSize = window()->size();
if (windowSize != bufferSize())
setBufferSize(windowSize);
@@ -526,8 +540,12 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (m_screen == platformScreen)
return;
- if (m_screen)
+ if (m_screen) {
+ qWindowDebug() << Q_FUNC_INFO << "Moving window to different screen";
m_screen->removeWindow(this);
+ screen_leave_window_group(m_window);
+ }
+
platformScreen->addWindow(this);
m_screen = platformScreen;
@@ -538,17 +556,20 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (result != 0)
qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
- // Add window to display's window group
- errno = 0;
- result = screen_join_window_group(m_window, platformScreen->windowGroupName());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
- // Only subwindows and tooltips need necessarily be moved to another display with the window.
- if ((window()->type() & Qt::WindowType_Mask) == Qt::SubWindow ||
- (window()->type() & Qt::WindowType_Mask) == Qt::ToolTip)
- childWindow->setScreen(platformScreen);
+ if (m_screen->isPrimaryScreen()) {
+ // Add window to display's window group
+ errno = 0;
+ result = screen_join_window_group(m_window, platformScreen->windowGroupName());
+ if (result != 0)
+ qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
+
+ Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
+ // Only subwindows and tooltips need necessarily be moved to another display with the window.
+ if ((window()->type() & Qt::WindowType_Mask) == Qt::SubWindow ||
+ (window()->type() & Qt::WindowType_Mask) == Qt::ToolTip)
+ childWindow->setScreen(platformScreen);
+ }
}
m_screen->updateHierarchy();
@@ -586,8 +607,18 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
setScreen(m_parentWindow->m_screen);
m_parentWindow->m_childWindows.push_back(this);
+
+ // we don't need any buffers, since
+ // Qt will draw to the parent TLW
+ // backing store.
+ setBufferSize(QSize(1, 1));
} else {
m_screen->addWindow(this);
+
+ // recreate buffers, in case the
+ // window has been reparented and
+ // becomes a TLW
+ adjustBufferSize();
}
m_screen->updateHierarchy();
@@ -646,6 +677,12 @@ void QQnxWindow::setWindowState(Qt::WindowState state)
applyWindowState();
}
+void QQnxWindow::propagateSizeHints()
+{
+ // nothing to do; silence base class warning
+ qWindowDebug() << Q_FUNC_INFO << ": ignored";
+}
+
void QQnxWindow::gainedFocus()
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window();
@@ -711,6 +748,79 @@ void QQnxWindow::minimize()
#endif
}
+#if !defined(QT_NO_OPENGL)
+void QQnxWindow::createEGLSurface()
+{
+ // Fetch the surface size from the window and update
+ // the window's buffers before we create the EGL surface
+ const QSize surfaceSize = requestedBufferSize();
+ if (!surfaceSize.isValid()) {
+ qFatal("QQNX: Trying to create 0 size EGL surface. "
+ "Please set a valid window size before calling QOpenGLContext::makeCurrent()");
+ }
+ setBufferSize(surfaceSize);
+
+ // Post root window, in case it hasn't been posted yet, to make it appear.
+ screen()->onWindowPost(0);
+
+ const EGLint eglSurfaceAttrs[] =
+ {
+ EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
+ EGL_NONE
+ };
+
+ qWindowDebug() << "Creating EGL surface" << platformOpenGLContext()->getEglDisplay()
+ << platformOpenGLContext()->getEglConfig();
+ // Create EGL surface
+ m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay()
+ , platformOpenGLContext()->getEglConfig(),
+ (EGLNativeWindowType) m_window, eglSurfaceAttrs);
+ if (m_eglSurface == EGL_NO_SURFACE) {
+ QQnxGLContext::checkEGLError("eglCreateWindowSurface");
+ qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError());
+ }
+}
+
+void QQnxWindow::destroyEGLSurface()
+{
+ // Destroy EGL surface if it exists
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ EGLBoolean eglResult = eglDestroySurface(platformOpenGLContext()->getEglDisplay(), m_eglSurface);
+ if (eglResult != EGL_TRUE)
+ qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
+ }
+
+ m_eglSurface = EGL_NO_SURFACE;
+}
+
+void QQnxWindow::swapEGLBuffers()
+{
+ qWindowDebug() << Q_FUNC_INFO;
+ // Set current rendering API
+ EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
+ if (eglResult != EGL_TRUE)
+ qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
+
+ // Post EGL surface to window
+ eglResult = eglSwapBuffers(m_platformOpenGLContext->getEglDisplay(), m_eglSurface);
+ if (eglResult != EGL_TRUE)
+ qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError());
+}
+
+EGLSurface QQnxWindow::getSurface()
+{
+ if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ platformOpenGLContext()->doneCurrent();
+ destroyEGLSurface();
+ }
+ createEGLSurface();
+ }
+
+ return m_eglSurface;
+}
+#endif
+
void QQnxWindow::updateZorder(int &topZorder)
{
errno = 0;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 63d5dc0979..4fabccf4cb 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -103,6 +103,8 @@ public:
void requestActivateWindow();
void setWindowState(Qt::WindowState state);
+ void propagateSizeHints();
+
void gainedFocus();
QQnxScreen *screen() const { return m_screen; }
@@ -118,6 +120,13 @@ public:
void blitFrom(QQnxWindow *sourceWindow, const QPoint &sourceOffset, const QRegion &targetRegion);
void minimize();
+#if !defined(QT_NO_OPENGL)
+ void createEGLSurface();
+ void destroyEGLSurface();
+ void swapEGLBuffers();
+ EGLSurface getSurface();
+#endif
+
private:
QRect setGeometryHelper(const QRect &rect);
void removeFromParent();
@@ -145,9 +154,6 @@ private:
QRegion m_previousDirty;
QRegion m_scrolled;
-#if !defined(QT_NO_OPENGL)
- QQnxGLContext *m_platformOpenGLContext;
-#endif
QQnxScreen *m_screen;
QList<QQnxWindow*> m_childWindows;
QQnxWindow *m_parentWindow;
@@ -162,6 +168,13 @@ private:
// EGL surface. All of this has to be done from the thread that is calling
// QQnxGLContext::makeCurrent()
mutable QMutex m_mutex;
+
+#if !defined(QT_NO_OPENGL)
+ QQnxGLContext *m_platformOpenGLContext;
+ QAtomicInt m_newSurfaceRequested;
+ EGLSurface m_eglSurface;
+#endif
+
QSize m_requestedBufferSize;
};
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index 7a28fd9074..a0f2c1812f 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -1207,10 +1207,14 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowColumnExtents(long *row,
{
QAccessibleInterface *accessible = accessibleInterface();
accessibleDebugClientCalls(accessible);
- if (!accessible)
+ if (!accessible || !tableCellInterface())
return E_FAIL;
- tableCellInterface()->rowColumnExtents((int*)row, (int*)column, (int*)rowExtents, (int*)columnExtents, (bool*)isSelected);
+ *row = (long)tableCellInterface()->rowIndex();
+ *column = (long)tableCellInterface()->columnIndex();
+ *rowExtents = (long)tableCellInterface()->rowExtent();
+ *columnExtents = (long)tableCellInterface()->columnExtent();
+ *isSelected = tableCellInterface()->isSelected();
return S_OK;
}
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
index e5c3269a6c..ffd87af193 100644
--- a/src/plugins/platforms/windows/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -105,12 +105,12 @@ QT_BEGIN_NAMESPACE
class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "windows.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "windows.json")
public:
- QPlatformIntegration *create(const QString&, const QStringList&);
+ QPlatformIntegration *create(const QString&, const QStringList&, int &, char **);
};
-QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList, int &, char **)
{
if (system.compare(system, QStringLiteral("windows"), Qt::CaseInsensitive) == 0)
return new QWindowsIntegration(paramList);
diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h
index 49ddf3106b..4c08a664d8 100644
--- a/src/plugins/platforms/windows/qtwindows_additional.h
+++ b/src/plugins/platforms/windows/qtwindows_additional.h
@@ -49,6 +49,10 @@
# define WM_THEMECHANGED 0x031A
#endif
+#ifndef WM_DWMCOMPOSITIONCHANGED
+# define WM_DWMCOMPOSITIONCHANGED 0x31E
+#endif
+
#ifndef GWL_HWNDPARENT
# define GWL_HWNDPARENT (-8)
#endif
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 238817e85c..e9eb50799e 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -83,6 +83,7 @@ enum WindowsEventType // Simplify event types
CalculateSize = WindowEventFlag + 16,
FocusInEvent = WindowEventFlag + 17,
FocusOutEvent = WindowEventFlag + 18,
+ WhatsThisEvent = WindowEventFlag + 19,
MouseEvent = MouseEventFlag + 1,
MouseWheelEvent = MouseEventFlag + 2,
CursorEvent = MouseEventFlag + 3,
@@ -104,6 +105,7 @@ enum WindowsEventType // Simplify event types
InputMethodCloseCandidateWindowEvent = InputMethodEventFlag + 5,
InputMethodRequest = InputMethodEventFlag + 6,
ThemeChanged = ThemingEventFlag + 1,
+ CompositionSettingsChanged = ThemingEventFlag + 2,
DisplayChangedEvent = 437,
SettingChangedEvent = DisplayChangedEvent + 1,
ContextMenu = 123,
@@ -200,10 +202,18 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return QtWindows::DisplayChangedEvent;
case WM_THEMECHANGED:
return QtWindows::ThemeChanged;
+ case WM_DWMCOMPOSITIONCHANGED:
+ return QtWindows::CompositionSettingsChanged;
#ifndef QT_NO_CONTEXTMENU
case WM_CONTEXTMENU:
return QtWindows::ContextMenu;
#endif
+ case WM_SYSCOMMAND:
+#ifndef Q_OS_WINCE
+ if ((wParamIn & 0xfff0) == SC_CONTEXTHELP)
+ return QtWindows::WhatsThisEvent;
+#endif
+ break;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 5114e9d524..8dab1e2b1c 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -47,6 +47,7 @@
#include "qtwindowsglobal.h"
#include "qwindowsmime.h"
#include "qwindowsinputcontext.h"
+#include "qwindowstabletsupport.h"
#ifndef QT_NO_ACCESSIBILITY
#include "accessible/qwindowsaccessibility.h"
#endif
@@ -83,6 +84,7 @@ int QWindowsContext::verboseOLE = 0;
int QWindowsContext::verboseInputMethods = 0;
int QWindowsContext::verboseDialogs = 0;
int QWindowsContext::verboseTheming = 0;
+int QWindowsContext::verboseTablet = 0;
// Get verbosity of components from "foo:2,bar:3"
static inline int componentVerbose(const char *v, const char *keyWord)
@@ -216,6 +218,7 @@ bool QWindowsUser32DLL::initTouch()
QWindowsShell32DLL::QWindowsShell32DLL()
: sHCreateItemFromParsingName(0)
, sHGetStockIconInfo(0)
+ , sHGetImageList(0)
{
}
@@ -224,6 +227,7 @@ void QWindowsShell32DLL::init()
QSystemLibrary library(QStringLiteral("shell32"));
sHCreateItemFromParsingName = (SHCreateItemFromParsingName)(library.resolve("SHCreateItemFromParsingName"));
sHGetStockIconInfo = (SHGetStockIconInfo)library.resolve("SHGetStockIconInfo");
+ sHGetImageList = (SHGetImageList)library.resolve("SHGetImageList");
}
QWindowsUser32DLL QWindowsContext::user32dll;
@@ -259,17 +263,20 @@ struct QWindowsContextPrivate {
QWindowsMimeConverter m_mimeConverter;
QWindowsScreenManager m_screenManager;
QSharedPointer<QWindowCreationContext> m_creationContext;
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ QScopedPointer<QWindowsTabletSupport> m_tabletSupport;
+#endif
const HRESULT m_oleInitializeResult;
const QByteArray m_eventType;
QWindow *m_lastActiveWindow;
bool m_asyncExpose;
};
-QWindowsContextPrivate::QWindowsContextPrivate() :
- m_systemInfo(0),
- m_oleInitializeResult(OleInitialize(NULL)),
- m_eventType(QByteArrayLiteral("windows_generic_MSG")),
- m_lastActiveWindow(0), m_asyncExpose(0)
+QWindowsContextPrivate::QWindowsContextPrivate()
+ : m_systemInfo(0)
+ , m_oleInitializeResult(OleInitialize(NULL))
+ , m_eventType(QByteArrayLiteral("windows_generic_MSG"))
+ , m_lastActiveWindow(0), m_asyncExpose(0)
{
const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
#ifndef Q_OS_WINCE
@@ -310,7 +317,13 @@ QWindowsContext::QWindowsContext() :
QWindowsContext::verboseInputMethods = componentVerbose(v, "im");
QWindowsContext::verboseDialogs = componentVerbose(v, "dialogs");
QWindowsContext::verboseTheming = componentVerbose(v, "theming");
+ QWindowsContext::verboseTablet = componentVerbose(v, "tablet");
}
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ d->m_tabletSupport.reset(QWindowsTabletSupport::create());
+ if (QWindowsContext::verboseTablet)
+ qDebug() << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
+#endif
}
QWindowsContext::~QWindowsContext()
@@ -631,6 +644,15 @@ QWindowsScreenManager &QWindowsContext::screenManager()
return d->m_screenManager;
}
+QWindowsTabletSupport *QWindowsContext::tabletSupport() const
+{
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ return d->m_tabletSupport.data();
+#else
+ return 0;
+#endif
+}
+
/*!
\brief Convenience to create a non-visible, message-only dummy
window for example used as clipboard watcher or for GL.
@@ -864,8 +886,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
theme->windowsThemeChanged(platformWindow->window());
return true;
}
+ case QtWindows::CompositionSettingsChanged:
+ platformWindow->handleCompositionSettingsChanged();
+ return true;
#ifndef Q_OS_WINCE
case QtWindows::ActivateWindowEvent:
+#ifndef QT_NO_TABLETEVENT
+ if (!d->m_tabletSupport.isNull())
+ d->m_tabletSupport->notifyActivate();
+#endif // !QT_NO_TABLETEVENT
if (platformWindow->testFlag(QWindowsWindow::BlockedByModal))
if (const QWindow *modalWindow = QGuiApplication::modalWindow())
QWindowsWindow::baseWindowOf(modalWindow)->alertWindow();
@@ -875,6 +904,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::ContextMenu:
return handleContextMenuEvent(platformWindow->window(), msg);
#endif
+ case QtWindows::WhatsThisEvent: {
+#ifndef QT_NO_WHATSTHIS
+ QWindowSystemInterface::handleEnterWhatsThisEvent();
+ return true;
+#endif
+ } break;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 6b80075379..173df58570 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE
class QWindow;
class QPlatformScreen;
class QWindowsScreenManager;
+class QWindowsTabletSupport;
class QWindowsWindow;
class QWindowsMimeConverter;
struct QWindowCreationContext;
@@ -107,9 +108,11 @@ struct QWindowsShell32DLL
typedef HRESULT (WINAPI *SHCreateItemFromParsingName)(PCWSTR, IBindCtx *, const GUID&, void **);
typedef HRESULT (WINAPI *SHGetStockIconInfo)(int , int , _SHSTOCKICONINFO *);
+ typedef HRESULT (WINAPI *SHGetImageList)(int, REFIID , void **);
SHCreateItemFromParsingName sHCreateItemFromParsingName;
SHGetStockIconInfo sHGetStockIconInfo;
+ SHGetImageList sHGetImageList;
};
#endif // Q_OS_WINCE
@@ -135,6 +138,7 @@ public:
static int verboseInputMethods;
static int verboseDialogs;
static int verboseTheming;
+ static int verboseTablet;
explicit QWindowsContext();
~QWindowsContext();
@@ -185,6 +189,7 @@ public:
QWindowsMimeConverter &mimeConverter() const;
QWindowsScreenManager &screenManager();
+ QWindowsTabletSupport *tabletSupport() const;
#ifndef Q_OS_WINCE
static QWindowsUser32DLL user32dll;
static QWindowsShell32DLL shell32dll;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 9a7d03c0c2..0e6c49aedb 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#define QT_NO_URL_CAST_FROM_STRING 1
+
#include "qwindowsdialoghelpers.h"
#include "qwindowscontext.h"
@@ -64,6 +66,8 @@
#include <QtCore/QMutexLocker>
#include <QtCore/private/qsystemlibrary_p.h>
+#include <algorithm>
+
#include "qtwindows_additional.h"
#define STRICT_TYPED_ITEMIDS
@@ -613,24 +617,6 @@ void QWindowsDialogHelperBase<BaseClass>::exec()
}
}
-static inline bool snapToDefaultButtonHint()
-{
- BOOL snapToDefault = false;
- if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0))
- return snapToDefault;
- return false;
-}
-
-template <class BaseClass>
-QVariant QWindowsDialogHelperBase<BaseClass>::styleHint(QPlatformDialogHelper::StyleHint hint) const
-{
- switch (hint) {
- case QPlatformDialogHelper::SnapToDefaultButton:
- return QVariant(snapToDefaultButtonHint());
- }
- return BaseClass::styleHint(hint);
-}
-
/*!
\class QWindowsFileDialogSharedData
\brief Explicitly shared file dialog parameters that are not in QFileDialogOptions.
@@ -651,34 +637,34 @@ public:
QWindowsFileDialogSharedData() : m_data(new Data) {}
void fromOptions(const QSharedPointer<QFileDialogOptions> &o);
- QString directory() const;
- void setDirectory(const QString &);
+ QUrl directory() const;
+ void setDirectory(const QUrl &);
QString selectedNameFilter() const;
void setSelectedNameFilter(const QString &);
- QStringList selectedFiles() const;
- void setSelectedFiles(const QStringList &);
+ QList<QUrl> selectedFiles() const;
+ void setSelectedFiles(const QList<QUrl> &);
QString selectedFile() const;
private:
class Data : public QSharedData {
public:
- QString directory;
+ QUrl directory;
QString selectedNameFilter;
- QStringList selectedFiles;
+ QList<QUrl> selectedFiles;
QMutex mutex;
};
QExplicitlySharedDataPointer<Data> m_data;
};
-inline QString QWindowsFileDialogSharedData::directory() const
+inline QUrl QWindowsFileDialogSharedData::directory() const
{
m_data->mutex.lock();
- const QString result = m_data->directory;
+ const QUrl result = m_data->directory;
m_data->mutex.unlock();
return result;
}
-inline void QWindowsFileDialogSharedData::setDirectory(const QString &d)
+inline void QWindowsFileDialogSharedData::setDirectory(const QUrl &d)
{
QMutexLocker (&m_data->mutex);
m_data->directory = d;
@@ -698,24 +684,24 @@ inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f
m_data->selectedNameFilter = f;
}
-inline QStringList QWindowsFileDialogSharedData::selectedFiles() const
+inline QList<QUrl> QWindowsFileDialogSharedData::selectedFiles() const
{
m_data->mutex.lock();
- const QStringList result = m_data->selectedFiles;
+ const QList<QUrl> result = m_data->selectedFiles;
m_data->mutex.unlock();
return result;
}
inline QString QWindowsFileDialogSharedData::selectedFile() const
{
- const QStringList files = selectedFiles();
- return files.isEmpty() ? QString() : files.front();
+ const QList<QUrl> files = selectedFiles();
+ return files.isEmpty() ? QString() : files.front().toLocalFile();
}
-inline void QWindowsFileDialogSharedData::setSelectedFiles(const QStringList &f)
+inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &urls)
{
QMutexLocker (&m_data->mutex);
- m_data->selectedFiles = f;
+ m_data->selectedFiles = urls;
}
inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o)
@@ -779,7 +765,7 @@ public:
QWindowsNativeFileDialogEventHandler(QWindowsNativeFileDialogBase *nativeFileDialog) :
m_ref(1), m_nativeFileDialog(nativeFileDialog) {}
- ~QWindowsNativeFileDialogEventHandler() {}
+ virtual ~QWindowsNativeFileDialogEventHandler() {}
private:
long m_ref;
@@ -822,7 +808,7 @@ public:
virtual void setWindowTitle(const QString &title);
inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::FileDialogOptions options);
inline void setDirectory(const QString &directory);
- inline void updateDirectory() { setDirectory(m_data.directory()); }
+ inline void updateDirectory() { setDirectory(m_data.directory().toLocalFile()); }
inline QString directory() const;
virtual void exec(HWND owner = 0);
virtual void setNameFilters(const QStringList &f);
@@ -837,10 +823,10 @@ public:
inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text);
// Return the selected files for tracking in OnSelectionChanged().
- virtual QStringList selectedFiles() const = 0;
+ virtual QList<QUrl> selectedFiles() const = 0;
// Return the result for tracking in OnFileOk(). Differs from selection for
// example by appended default suffixes, etc.
- virtual QStringList dialogResult() const = 0;
+ virtual QList<QUrl> dialogResult() const = 0;
inline void onFolderChange(IShellItem *);
inline void onSelectionChange();
@@ -848,8 +834,8 @@ public:
inline bool onFileOk();
signals:
- void directoryEntered(const QString& directory);
- void currentChanged(const QString& file);
+ void directoryEntered(const QUrl &directory);
+ void currentChanged(const QUrl &file);
void filterSelected(const QString & filter);
public slots:
@@ -861,9 +847,9 @@ protected:
void setDefaultSuffixSys(const QString &s);
inline IFileDialog * fileDialog() const { return m_fileDialog; }
static QString itemPath(IShellItem *item);
- static QStringList libraryItemFolders(IShellItem *item);
+ static QList<QUrl> libraryItemFolders(IShellItem *item);
static QString libraryItemDefaultSaveFolder(IShellItem *item);
- static int itemPaths(IShellItemArray *items, QStringList *fileResult = 0);
+ static int itemPaths(IShellItemArray *items, QList<QUrl> *fileResult = 0);
static IShellItem *shellItem(const QString &path);
const QWindowsFileDialogSharedData &data() const { return m_data; }
@@ -1031,9 +1017,9 @@ static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode)
}
// Return all folders of a library-type item.
-QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item)
+QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item)
{
- QStringList result;
+ QList<QUrl> result;
if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) {
IShellItemArray *itemArray = 0;
if (SUCCEEDED(library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, reinterpret_cast<void **>(&itemArray)))) {
@@ -1062,9 +1048,9 @@ QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *i
#else // !Q_OS_WINCE && __IShellLibrary_INTERFACE_DEFINED__
-QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *)
+QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *)
{
- return QStringList();
+ return QList<QUrl>();
}
QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *)
@@ -1096,7 +1082,7 @@ QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item)
}
int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items,
- QStringList *result /* = 0 */)
+ QList<QUrl> *result /* = 0 */)
{
DWORD itemCount = 0;
if (result)
@@ -1108,7 +1094,7 @@ int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items,
for (DWORD i = 0; i < itemCount; ++i) {
IShellItem *item = 0;
if (SUCCEEDED(items->GetItemAt(i, &item)))
- result->push_back(QWindowsNativeFileDialogBase::itemPath(item));
+ result->push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
}
}
return itemCount;
@@ -1270,7 +1256,7 @@ QString QWindowsNativeFileDialogBase::selectedNameFilter() const
void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item)
{
if (item) {
- const QString directory = QWindowsNativeFileDialogBase::itemPath(item);
+ const QUrl directory = QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item));
m_data.setDirectory(directory);
emit directoryEntered(directory);
}
@@ -1278,7 +1264,7 @@ void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item)
void QWindowsNativeFileDialogBase::onSelectionChange()
{
- const QStringList current = selectedFiles();
+ const QList<QUrl> current = selectedFiles();
m_data.setSelectedFiles(current);
if (current.size() == 1)
emit currentChanged(current.front());
@@ -1338,8 +1324,8 @@ public:
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data)
: QWindowsNativeFileDialogBase(data) {}
virtual void setNameFilters(const QStringList &f);
- virtual QStringList selectedFiles() const;
- virtual QStringList dialogResult() const;
+ virtual QList<QUrl> selectedFiles() const;
+ virtual QList<QUrl> dialogResult() const;
};
// Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo".
@@ -1374,22 +1360,22 @@ void QWindowsNativeSaveFileDialog::setNameFilters(const QStringList &f)
} // m_hasDefaultSuffix
}
-QStringList QWindowsNativeSaveFileDialog::dialogResult() const
+QList<QUrl> QWindowsNativeSaveFileDialog::dialogResult() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItem *item = 0;
if (SUCCEEDED(fileDialog()->GetResult(&item)) && item)
- result.push_back(QWindowsNativeFileDialogBase::itemPath(item));
+ result.push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
return result;
}
-QStringList QWindowsNativeSaveFileDialog::selectedFiles() const
+QList<QUrl> QWindowsNativeSaveFileDialog::selectedFiles() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItem *item = 0;
const HRESULT hr = fileDialog()->GetCurrentSelection(&item);
if (SUCCEEDED(hr) && item)
- result.push_back(QWindowsNativeSaveFileDialog::itemPath(item));
+ result.push_back(QUrl::fromLocalFile(QWindowsNativeSaveFileDialog::itemPath(item)));
return result;
}
@@ -1408,26 +1394,26 @@ class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase
public:
explicit QWindowsNativeOpenFileDialog(const QWindowsFileDialogSharedData &data) :
QWindowsNativeFileDialogBase(data) {}
- virtual QStringList selectedFiles() const;
- virtual QStringList dialogResult() const;
+ virtual QList<QUrl> selectedFiles() const;
+ virtual QList<QUrl> dialogResult() const;
private:
inline IFileOpenDialog *openFileDialog() const
{ return static_cast<IFileOpenDialog *>(fileDialog()); }
};
-QStringList QWindowsNativeOpenFileDialog::dialogResult() const
+QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItemArray *items = 0;
if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items)
QWindowsNativeFileDialogBase::itemPaths(items, &result);
return result;
}
-QStringList QWindowsNativeOpenFileDialog::selectedFiles() const
+QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItemArray *items = 0;
const HRESULT hr = openFileDialog()->GetSelectedItems(&items);
if (SUCCEEDED(hr) && items)
@@ -1484,14 +1470,13 @@ public:
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
- virtual void setDirectory(const QString &directory);
- virtual QString directory() const;
- virtual void selectFile(const QString &filename);
- virtual QStringList selectedFiles() const;
- virtual void setFilter();
- virtual void setNameFilters(const QStringList &filters);
- virtual void selectNameFilter(const QString &filter);
- virtual QString selectedNameFilter() const;
+ virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ virtual QUrl directory() const Q_DECL_OVERRIDE;
+ virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
+ virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ virtual void setFilter() Q_DECL_OVERRIDE;
+ virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE;
+ virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
virtual QWindowsNativeDialogBase *createNativeDialog();
@@ -1509,10 +1494,10 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
return 0;
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()));
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()));
- QObject::connect(result, SIGNAL(directoryEntered(QString)),
- this, SIGNAL(directoryEntered(QString)));
- QObject::connect(result, SIGNAL(currentChanged(QString)),
- this, SIGNAL(currentChanged(QString)));
+ QObject::connect(result, SIGNAL(directoryEntered(QUrl)),
+ this, SIGNAL(directoryEntered(QUrl)));
+ QObject::connect(result, SIGNAL(currentChanged(QUrl)),
+ this, SIGNAL(currentChanged(QUrl)));
QObject::connect(result, SIGNAL(filterSelected(QString)),
this, SIGNAL(filterSelected(QString)));
@@ -1532,11 +1517,16 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
result->setLabelText(QFileDialogOptions::Accept, opts->labelText(QFileDialogOptions::Accept));
result->updateDirectory();
result->updateSelectedNameFilter();
- const QStringList initialSelection = opts->initiallySelectedFiles();
+ const QList<QUrl> initialSelection = opts->initiallySelectedFiles();
if (initialSelection.size() > 0) {
- QFileInfo info(initialSelection.front());
- if (!info.isDir())
- result->selectFile(info.fileName());
+ const QUrl url = initialSelection.front();
+ if (url.isLocalFile()) {
+ QFileInfo info(url.toLocalFile());
+ if (!info.isDir())
+ result->selectFile(info.fileName());
+ } else {
+ result->selectFile(url.path()); // TODO url.fileName() once it exists
+ }
}
// No need to select initialNameFilter if mode is Dir
if (mode != QFileDialogOptions::Directory && mode != QFileDialogOptions::DirectoryOnly) {
@@ -1550,31 +1540,31 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
return result;
}
-void QWindowsFileDialogHelper::setDirectory(const QString &directory)
+void QWindowsFileDialogHelper::setDirectory(const QUrl &directory)
{
if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(directory));
+ qDebug("%s %s" , __FUNCTION__, qPrintable(directory.toString()));
m_data.setDirectory(directory);
if (hasNativeDialog())
nativeFileDialog()->updateDirectory();
}
-QString QWindowsFileDialogHelper::directory() const
+QUrl QWindowsFileDialogHelper::directory() const
{
return m_data.directory();
}
-void QWindowsFileDialogHelper::selectFile(const QString &fileName)
+void QWindowsFileDialogHelper::selectFile(const QUrl &fileName)
{
if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(fileName));
+ qDebug("%s %s" , __FUNCTION__, qPrintable(fileName.toString()));
if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog())
- nfd->selectFile(fileName);
+ nfd->selectFile(fileName.toLocalFile()); // ## should use QUrl::fileName() once it exists
}
-QStringList QWindowsFileDialogHelper::selectedFiles() const
+QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
{
return m_data.selectedFiles();
}
@@ -1585,14 +1575,6 @@ void QWindowsFileDialogHelper::setFilter()
qDebug("%s" , __FUNCTION__);
}
-void QWindowsFileDialogHelper::setNameFilters(const QStringList &filters)
-{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s" , __FUNCTION__);
- if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog())
- nfd->setNameFilters(filters);
-}
-
void QWindowsFileDialogHelper::selectNameFilter(const QString &filter)
{
m_data.setSelectedNameFilter(filter);
@@ -1643,8 +1625,8 @@ private:
explicit QWindowsXpNativeFileDialog(const OptionsPtr &options, const QWindowsFileDialogSharedData &data);
void populateOpenFileName(OPENFILENAME *ofn, HWND owner) const;
- QStringList execExistingDir(HWND owner);
- QStringList execFileNames(HWND owner, int *selectedFilterIndex) const;
+ QList<QUrl> execExistingDir(HWND owner);
+ QList<QUrl> execFileNames(HWND owner, int *selectedFilterIndex) const;
const OptionsPtr m_options;
QString m_title;
@@ -1683,7 +1665,7 @@ QWindowsXpNativeFileDialog::QWindowsXpNativeFileDialog(const OptionsPtr &options
void QWindowsXpNativeFileDialog::exec(HWND owner)
{
int selectedFilterIndex = -1;
- const QStringList selectedFiles =
+ const QList<QUrl> selectedFiles =
m_options->fileMode() == QFileDialogOptions::DirectoryOnly ?
execExistingDir(owner) : execFileNames(owner, &selectedFilterIndex);
m_data.setSelectedFiles(selectedFiles);
@@ -1695,7 +1677,8 @@ void QWindowsXpNativeFileDialog::exec(HWND owner)
const QStringList nameFilters = m_options->nameFilters();
if (selectedFilterIndex >= 0 && selectedFilterIndex < nameFilters.size())
m_data.setSelectedNameFilter(nameFilters.at(selectedFilterIndex));
- m_data.setDirectory(QFileInfo(selectedFiles.front()).absolutePath());
+ QUrl firstFile = selectedFiles.front();
+ m_data.setDirectory(firstFile.adjusted(QUrl::RemoveFilename));
m_result = QPlatformDialogHelper::Accepted;
emit accepted();
}
@@ -1722,7 +1705,7 @@ int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM
case BFFM_INITIALIZED: {
if (!m_title.isEmpty())
SetWindowText(hwnd, (wchar_t *)m_title.utf16());
- const QString initialFile = QDir::toNativeSeparators(m_data.directory());
+ const QString initialFile = QDir::toNativeSeparators(m_data.directory().toLocalFile());
if (!initialFile.isEmpty())
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initialFile.utf16()));
}
@@ -1738,7 +1721,7 @@ int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM
return 0;
}
-QStringList QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
+QList<QUrl> QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
{
BROWSEINFO bi;
wchar_t initPath[MAX_PATH];
@@ -1750,12 +1733,12 @@ QStringList QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
bi.lpfn = xpFileDialogGetExistingDirCallbackProc;
bi.lParam = LPARAM(this);
- QStringList selectedFiles;
+ QList<QUrl> selectedFiles;
if (qt_LpItemIdList pItemIDList = SHBrowseForFolder(&bi)) {
wchar_t path[MAX_PATH];
path[0] = 0;
if (SHGetPathFromIDList(pItemIDList, path) && path[0])
- selectedFiles.push_back(QDir::cleanPath(QString::fromWCharArray(path)));
+ selectedFiles.push_back(QUrl::fromLocalFile(QDir::cleanPath(QString::fromWCharArray(path))));
IMalloc *pMalloc;
if (SHGetMalloc(&pMalloc) == NOERROR) {
pMalloc->Free(pItemIDList);
@@ -1807,7 +1790,7 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
QDir::toNativeSeparators(m_data.selectedFile()).remove(QLatin1Char('<')).
remove(QLatin1Char('>')).remove(QLatin1Char('"')).remove(QLatin1Char('|'));
ofn->lpstrFile = qStringToWCharArray(initiallySelectedFile, ofn->nMaxFile);
- ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory()));
+ ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory().toLocalFile()));
ofn->lpstrTitle = (wchar_t*)m_title.utf16();
// Determine lpstrDefExt. Note that the current MSDN docs document this
// member wrong. It should rather be documented as "the default extension
@@ -1832,25 +1815,27 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
ofn->Flags |= OFN_OVERWRITEPROMPT;
}
-QStringList QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedFilterIndex) const
+QList<QUrl> QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedFilterIndex) const
{
*selectedFilterIndex = -1;
OPENFILENAME ofn;
populateOpenFileName(&ofn, owner);
- QStringList result;
+ QList<QUrl> result;
const bool isSave = m_options->acceptMode() == QFileDialogOptions::AcceptSave;
if (isSave ? m_getSaveFileNameW(&ofn) : m_getOpenFileNameW(&ofn)) {
*selectedFilterIndex = ofn.nFilterIndex - 1;
- result.push_back(QDir::cleanPath(QString::fromWCharArray(ofn.lpstrFile)));
+ const QString dir = QDir::cleanPath(QString::fromWCharArray(ofn.lpstrFile));
+ result.push_back(QUrl::fromLocalFile(dir));
// For multiselection, the first item is the path followed
// by "\0<file1>\0<file2>\0\0".
if (ofn.Flags & (OFN_ALLOWMULTISELECT)) {
- wchar_t *ptr = ofn.lpstrFile + result.front().size() + 1;
+ wchar_t *ptr = ofn.lpstrFile + dir.size() + 1;
if (*ptr) {
- const QString path = result.takeAt(0) + QLatin1Char('/');
+ result.pop_front();
+ const QString path = dir + QLatin1Char('/');
while (*ptr) {
const QString fileName = QString::fromWCharArray(ptr);
- result.push_back(path + fileName);
+ result.push_back(QUrl::fromLocalFile(path + fileName));
ptr += fileName.size() + 1;
} // extract multiple files
} // has multiple files
@@ -1879,14 +1864,13 @@ public:
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
- virtual void setDirectory(const QString &directory);
- virtual QString directory() const;
- virtual void selectFile(const QString &filename);
- virtual QStringList selectedFiles() const;
- virtual void setFilter() {}
- virtual void setNameFilters(const QStringList &);
- virtual void selectNameFilter(const QString &);
- virtual QString selectedNameFilter() const;
+ virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ virtual QUrl directory() const Q_DECL_OVERRIDE;
+ virtual void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
+ virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ virtual void setFilter() Q_DECL_OVERRIDE {}
+ virtual void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
+ virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
virtual QWindowsNativeDialogBase *createNativeDialog();
@@ -1907,31 +1891,26 @@ QWindowsNativeDialogBase *QWindowsXpFileDialogHelper::createNativeDialog()
return 0;
}
-void QWindowsXpFileDialogHelper::setDirectory(const QString &directory)
+void QWindowsXpFileDialogHelper::setDirectory(const QUrl &directory)
{
m_data.setDirectory(directory); // Dialog cannot be updated at run-time.
}
-QString QWindowsXpFileDialogHelper::directory() const
+QUrl QWindowsXpFileDialogHelper::directory() const
{
return m_data.directory();
}
-void QWindowsXpFileDialogHelper::selectFile(const QString &filename)
+void QWindowsXpFileDialogHelper::selectFile(const QUrl &url)
{
- m_data.setSelectedFiles(QStringList(filename)); // Dialog cannot be updated at run-time.
+ m_data.setSelectedFiles(QList<QUrl>() << url); // Dialog cannot be updated at run-time.
}
-QStringList QWindowsXpFileDialogHelper::selectedFiles() const
+QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
{
return m_data.selectedFiles();
}
-void QWindowsXpFileDialogHelper::setNameFilters(const QStringList &)
-{
- // Dialog cannot be updated at run-time.
-}
-
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
{
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
@@ -1984,7 +1963,7 @@ private:
QWindowsNativeColorDialog::QWindowsNativeColorDialog(const SharedPointerColor &color) :
m_code(QPlatformDialogHelper::Rejected), m_color(color)
{
- qFill(m_customColors, m_customColors + 16, COLORREF(0));
+ std::fill(m_customColors, m_customColors + 16, COLORREF(0));
}
void QWindowsNativeColorDialog::exec(HWND owner)
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
index 7884f398f3..c0ee60cc1e 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
@@ -72,7 +72,6 @@ public:
Qt::WindowModality windowModality,
QWindow *parent);
virtual void hide();
- virtual QVariant styleHint(QPlatformDialogHelper::StyleHint) const;
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; }
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index b7ccb5767e..a6bce6502b 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -838,8 +838,6 @@ error:
return i18n_name;
}
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
static bool addFontToDatabase(const QString &familyName, uchar charSet,
const TEXTMETRIC *textmetric,
const FONTSIGNATURE *signature,
@@ -932,7 +930,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0);
if (!englishName.isEmpty())
- qt_registerAliasToFontFamily(familyName, englishName);
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, englishName);
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 7f97d58be4..6037c201ac 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -122,8 +122,6 @@ static FontFile * createFontFile(const QString &fileName, int index)
extern bool localizedName(const QString &name);
extern QString getEnglishName(const QString &familyName);
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
static bool addFontToDatabase(const QString &familyName, uchar charSet,
const TEXTMETRIC *textmetric,
const FONTSIGNATURE *signature,
@@ -304,7 +302,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
if (!englishName.isEmpty())
- qt_registerAliasToFontFamily(faceName, englishName);
+ QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 33ddcaffc5..64457f4b67 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -1133,8 +1133,10 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
<< "If you need them anyway, start your application with -platform windows:fontengine=freetype.";
}
#endif // wince
- QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin + 4,
- ih + 2 * margin + 4,
+
+ // The padding here needs to be kept in sync with the values in alphaMapBoundingBox.
+ QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin,
+ ih + 2 * margin,
QWindowsNativeImage::systemFormat());
/*If cleartype is enabled we use the standard system format even on Windows CE
@@ -1167,6 +1169,17 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
return ni;
}
+glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat format)
+{
+ int margin = 0;
+ if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
+ margin = glyphMargin(QFontEngineGlyphCache::Raster_RGBMask);
+ glyph_metrics_t gm = boundingBox(glyph, matrix);
+ gm.width += margin * 2;
+ gm.height += margin * 2;
+ return gm;
+}
+
QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
{
HFONT font = hfont;
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index 9e92a8fbff..60ff61fcb9 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -121,6 +121,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform);
+ virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat);
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
virtual bool supportsTransformation(const QTransform &transform) const;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index c0f1b3a000..7407d88f8b 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -215,7 +215,9 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
if (QWindowsContext::verboseFonts)
qDebug("%s %g", __FUNCTION__, pixelSize);
- d->directWriteFactory->AddRef();
+ Q_ASSERT(m_directWriteFontFace);
+
+ m_fontEngineData->directWriteFactory->AddRef();
m_directWriteFontFace->AddRef();
fontDef.pixelSize = pixelSize;
@@ -237,19 +239,17 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
void QWindowsFontEngineDirectWrite::collectMetrics()
{
- if (m_directWriteFontFace != 0) {
- DWRITE_FONT_METRICS metrics;
-
- m_directWriteFontFace->GetMetrics(&metrics);
- m_unitsPerEm = metrics.designUnitsPerEm;
-
- m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
- m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
- m_descent = DESIGN_TO_LOGICAL(metrics.descent);
- m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
- m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
- m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
- }
+ DWRITE_FONT_METRICS metrics;
+
+ m_directWriteFontFace->GetMetrics(&metrics);
+ m_unitsPerEm = metrics.designUnitsPerEm;
+
+ m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
+ m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
+ m_descent = DESIGN_TO_LOGICAL(metrics.descent);
+ m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
+ m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
+ m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
}
QFixed QWindowsFontEngineDirectWrite::underlinePosition() const
@@ -272,31 +272,24 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui
{
bool ret = false;
- if (m_directWriteFontFace) {
- DWORD t = qbswap<quint32>(tag);
-
- const void *tableData = 0;
- void *tableContext = 0;
- UINT32 tableSize;
- BOOL exists;
- HRESULT hr = m_directWriteFontFace->TryGetFontTable(
- t, &tableData, &tableSize, &tableContext, &exists
- );
-
- if (SUCCEEDED(hr)) {
- if (exists) {
- if (!buffer) {
- *length = tableSize;
- ret = true;
- } else if (*length >= tableSize) {
- memcpy(buffer, tableData, tableSize);
- ret = true;
- }
- }
- m_directWriteFontFace->ReleaseFontTable(tableContext);
- } else {
- qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
+ const void *tableData = 0;
+ UINT32 tableSize;
+ void *tableContext = 0;
+ BOOL exists;
+ HRESULT hr = m_directWriteFontFace->TryGetFontTable(qbswap<quint32>(tag)
+ &tableData, &tableSize,
+ &tableContext, &exists);
+ if (SUCCEEDED(hr)) {
+ if (exists) {
+ ret = true;
+ if (buffer && *length >= tableSize)
+ memcpy(buffer, tableData, tableSize);
+ else
+ *length = tableSize;
}
+ m_directWriteFontFace->ReleaseFontTable(tableContext);
+ } else {
+ qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
}
return ret;
@@ -327,43 +320,43 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QFontEngine::ShaperFlags flags) const
{
- if (m_directWriteFontFace != 0) {
- QVarLengthArray<UINT32> codePoints(len);
- for (int i=0; i<len; ++i) {
- codePoints[i] = getChar(str, i, len);
- if (flags & QFontEngine::RightToLeft)
- codePoints[i] = QChar::mirroredChar(codePoints[i]);
- }
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
- QVarLengthArray<UINT16> glyphIndices(len);
- HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
- len,
- glyphIndices.data());
+ QVarLengthArray<UINT32> codePoints(len);
+ int actualLength = 0;
+ if (flags & QFontEngine::RightToLeft) {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
+ } else {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = getChar(str, i, len);
+ }
- if (SUCCEEDED(hr)) {
- for (int i=0; i<len; ++i)
- glyphs->glyphs[i] = glyphIndices[i];
+ QVarLengthArray<UINT16> glyphIndices(actualLength);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
+ glyphIndices.data());
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
+ return false;
+ }
- *nglyphs = len;
- glyphs->numGlyphs = len;
+ for (int i = 0; i < actualLength; ++i)
+ glyphs->glyphs[i] = glyphIndices.at(i);
- if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, 0);
+ *nglyphs = actualLength;
+ glyphs->numGlyphs = actualLength;
- return true;
- } else {
- qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
- }
- }
+ if (!(flags & GlyphIndicesOnly))
+ recalcAdvances(glyphs, 0);
- return false;
+ return true;
}
void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
// ### Caching?
@@ -391,9 +384,6 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags)
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(nglyphs);
QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
@@ -439,9 +429,6 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &g
glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
{
- if (m_directWriteFontFace == 0)
- return glyph_metrics_t();
-
UINT16 glyphIndex = g;
DWRITE_GLYPH_METRICS glyphMetrics;
@@ -668,14 +655,14 @@ bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len)
if (FAILED(hr)) {
qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__);
return false;
- } else {
- for (int i=0; i<glyphIndices.size(); ++i) {
- if (glyphIndices.at(i) == 0)
- return false;
- }
+ }
- return true;
+ for (int i = 0; i < actualLength; ++i) {
+ if (glyphIndices.at(i) == 0)
+ return false;
}
+
+ return true;
}
QFontEngine::Type QWindowsFontEngineDirectWrite::type() const
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index 106087f757..ab14cb49eb 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -107,8 +107,6 @@ public:
static QString fontNameSubstitute(const QString &familyName);
private:
- friend class QRawFontPrivate;
-
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index f6dda04c13..d1ede39549 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -49,6 +49,8 @@
#include <QtGui/QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
+#include <algorithm>
+
#include <wingdi.h>
#include <GL/gl.h>
@@ -377,7 +379,7 @@ static int choosePixelFormat(HDC hdc,
return 0;
int iAttributes[attribSize];
- qFill(iAttributes, iAttributes + attribSize, int(0));
+ std::fill(iAttributes, iAttributes + attribSize, int(0));
int i = 0;
iAttributes[i++] = WGL_ACCELERATION_ARB;
iAttributes[i++] = testFlag(additional.formatFlags, QWindowsGLDirectRendering) ?
@@ -505,8 +507,8 @@ static QSurfaceFormat
return result;
int iAttributes[attribSize];
int iValues[attribSize];
- qFill(iAttributes, iAttributes + attribSize, int(0));
- qFill(iValues, iValues + attribSize, int(0));
+ std::fill(iAttributes, iAttributes + attribSize, int(0));
+ std::fill(iValues, iValues + attribSize, int(0));
int i = 0;
const bool hasSampleBuffers = testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
@@ -567,7 +569,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
return 0;
int attributes[attribSize];
int attribIndex = 0;
- qFill(attributes, attributes + attribSize, int(0));
+ std::fill(attributes, attributes + attribSize, int(0));
// We limit the requested version by the version of the static context as
// wglCreateContextAttribsARB fails and returns NULL if the requested context
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
new file mode 100644
index 0000000000..4a5d7b5a78
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -0,0 +1,473 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowstabletsupport.h"
+
+#ifndef QT_NO_TABLETEVENT
+
+#include "qwindowscontext.h"
+#include "qwindowskeymapper.h"
+#include "qwindowswindow.h"
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtGui/QTabletEvent>
+#include <QtGui/QScreen>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+#include <QtCore/QScopedArrayPointer>
+#include <QtCore/QtMath>
+
+#include <private/qguiapplication_p.h>
+#include <QtCore/private/qsystemlibrary_p.h>
+
+// Note: The definition of the PACKET structure in pktdef.h depends on this define.
+#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z)
+#include <pktdef.h>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ PacketMode = 0,
+ TabletPacketQSize = 128,
+ DeviceIdMask = 0xFF6, // device type mask && device color mask
+ CursorTypeBitMask = 0x0F06 // bitmask to find the specific cursor type (see Wacom FAQ)
+};
+
+extern "C" LRESULT QT_WIN_CALLBACK qWindowsTabletSupportWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+ case WT_PROXIMITY:
+ if (QWindowsContext::instance()->tabletSupport()->translateTabletProximityEvent(wParam, lParam))
+ return 0;
+ break;
+ case WT_PACKET:
+ if (QWindowsContext::instance()->tabletSupport()->translateTabletPacketEvent())
+ return 0;
+ break;
+ }
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+
+// Scale tablet coordinates to screen coordinates.
+
+static inline int sign(int x)
+{
+ return x >= 0 ? 1 : -1;
+}
+
+inline QPointF QWindowsTabletDeviceData::scaleCoordinates(int coordX, int coordY, const QRect &targetArea) const
+{
+ const int targetX = targetArea.x();
+ const int targetY = targetArea.y();
+ const int targetWidth = targetArea.width();
+ const int targetHeight = targetArea.height();
+
+ const qreal x = sign(targetWidth) == sign(maxX) ?
+ ((coordX - minX) * qAbs(targetWidth) / qAbs(qreal(maxX - minX))) + targetX :
+ ((qAbs(maxX) - (coordX - minX)) * qAbs(targetWidth) / qAbs(qreal(maxX - minX))) + targetX;
+
+ const qreal y = sign(targetHeight) == sign(maxY) ?
+ ((coordY - minY) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY :
+ ((qAbs(maxY) - (coordY - minY)) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY;
+
+ return QPointF(x, y);
+}
+
+QWindowsWinTab32DLL QWindowsTabletSupport::m_winTab32DLL;
+
+/*!
+ \class QWindowsWinTab32DLL QWindowsTabletSupport
+ \brief Functions from wintabl32.dll shipped with WACOM tablets used by QWindowsTabletSupport.
+
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+bool QWindowsWinTab32DLL::init()
+{
+ if (wTInfo)
+ return true;
+ QSystemLibrary library(QStringLiteral("wintab32"));
+ if (!library.load())
+ return false;
+ wTOpen = (PtrWTOpen)library.resolve("WTOpenW");
+ wTClose = (PtrWTClose)library.resolve("WTClose");
+ wTInfo = (PtrWTInfo)library.resolve("WTInfoW");
+ wTEnable = (PtrWTEnable)library.resolve("WTEnable");
+ wTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
+ wTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
+ wTGet = (PtrWTGet)library.resolve("WTGetW");
+ wTQueueSizeGet = (PtrWTQueueSizeGet)library.resolve("WTQueueSizeGet");
+ wTQueueSizeSet = (PtrWTQueueSizeSet)library.resolve("WTQueueSizeSet");
+ return wTOpen && wTClose && wTInfo && wTEnable && wTOverlap && wTPacketsGet && wTQueueSizeGet && wTQueueSizeSet;
+}
+
+/*!
+ \class QWindowsTabletSupport
+ \brief Tablet support for Windows.
+
+ Support for WACOM tablets.
+
+ \sa http://www.wacomeng.com/windows/docs/Wintab_v140.htm
+
+ \internal
+ \since 5.2
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsTabletSupport::QWindowsTabletSupport(HWND window, HCTX context)
+ : m_window(window)
+ , m_context(context)
+ , m_tiltSupport(false)
+ , m_currentDevice(-1)
+{
+ AXIS orientation[3];
+ // Some tablets don't support tilt, check if it is possible,
+ if (QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES, DVC_ORIENTATION, &orientation))
+ m_tiltSupport = orientation[0].axResolution && orientation[1].axResolution;
+}
+
+QWindowsTabletSupport::~QWindowsTabletSupport()
+{
+ QWindowsTabletSupport::m_winTab32DLL.wTClose(m_context);
+ DestroyWindow(m_window);
+}
+
+QWindowsTabletSupport *QWindowsTabletSupport::create()
+{
+ if (!m_winTab32DLL.init())
+ return 0;
+ const HWND window = QWindowsContext::instance()->createDummyWindow(QStringLiteral("TabletDummyWindow"),
+ L"TabletDummyWindow",
+ qWindowsTabletSupportWndProc);
+ if (!window) {
+ if (QWindowsContext::verboseTablet)
+ qWarning() << __FUNCTION__ << "Unable to create window for tablet.";
+ return 0;
+ }
+ LOGCONTEXT lcMine;
+ // build our context from the default context
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFSYSCTX, 0, &lcMine);
+ // Go for the raw coordinates, the tablet event will return good stuff
+ lcMine.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
+ lcMine.lcPktData = lcMine.lcMoveMask = PACKETDATA;
+ lcMine.lcPktMode = PacketMode;
+ lcMine.lcOutOrgX = 0;
+ lcMine.lcOutExtX = lcMine.lcInExtX;
+ lcMine.lcOutOrgY = 0;
+ lcMine.lcOutExtY = -lcMine.lcInExtY;
+ const HCTX context = QWindowsTabletSupport::m_winTab32DLL.wTOpen(window, &lcMine, true);
+ if (!context) {
+ if (QWindowsContext::verboseTablet)
+ qWarning() << __FUNCTION__ << "Unable to open tablet.";
+ DestroyWindow(window);
+ return 0;
+
+ }
+ // Set the size of the Packet Queue to the correct size
+ const int currentQueueSize = QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeGet(context);
+ if (currentQueueSize != TabletPacketQSize) {
+ if (!QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeSet(context, TabletPacketQSize)) {
+ if (!QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeSet(context, currentQueueSize)) {
+ qWarning() << "Unable to set queue size on tablet. The tablet will not work.";
+ QWindowsTabletSupport::m_winTab32DLL.wTClose(context);
+ DestroyWindow(window);
+ return 0;
+ } // cannot restore old size
+ } // cannot set
+ } // mismatch
+ if (QWindowsContext::verboseTablet)
+ qDebug("Opened tablet context %p on window %p, changed packet queue size %d -> %d",
+ context, window, currentQueueSize, TabletPacketQSize);
+ return new QWindowsTabletSupport(window, context);
+}
+
+unsigned QWindowsTabletSupport::options() const
+{
+ UINT result = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_CTXOPTIONS, &result);
+ return result;
+}
+
+QString QWindowsTabletSupport::description() const
+{
+ const unsigned size = m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, 0);
+ if (!size)
+ return QString();
+ QScopedPointer<TCHAR> winTabId(new TCHAR[size + 1]);
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, winTabId.data());
+ WORD implementationVersion = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_IMPLVERSION, &implementationVersion);
+ WORD specificationVersion = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_SPECVERSION, &specificationVersion);
+ const unsigned opts = options();
+ QString result = QString::fromLatin1("%1 specification: v%2.%3 implementation: v%4.%5 options: 0x%6")
+ .arg(QString::fromWCharArray(winTabId.data()))
+ .arg(specificationVersion >> 8).arg(specificationVersion & 0xFF)
+ .arg(implementationVersion >> 8).arg(implementationVersion & 0xFF)
+ .arg(opts, 0, 16);
+ if (opts & CXO_MESSAGES)
+ result += QStringLiteral(" CXO_MESSAGES");
+ if (opts & CXO_CSRMESSAGES)
+ result += QStringLiteral(" CXO_CSRMESSAGES");
+ if (m_tiltSupport)
+ result += QStringLiteral(" tilt");
+ return result;
+}
+
+void QWindowsTabletSupport::notifyActivate()
+{
+ // Cooperate with other tablet applications, but when we get focus, I want to use the tablet.
+ const bool result = QWindowsTabletSupport::m_winTab32DLL.wTEnable(m_context, true)
+ && QWindowsTabletSupport::m_winTab32DLL.wTOverlap(m_context, true);
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << result;
+}
+
+static inline int indexOfDevice(const QVector<QWindowsTabletDeviceData> &devices, qint64 uniqueId)
+{
+ for (int i = 0; i < devices.size(); ++i)
+ if (devices.at(i).uniqueId == uniqueId)
+ return i;
+ return -1;
+}
+
+static inline QTabletEvent::TabletDevice deviceType(const UINT cursorType)
+{
+ if (((cursorType & 0x0006) == 0x0002) && ((cursorType & CursorTypeBitMask) != 0x0902))
+ return QTabletEvent::Stylus;
+ switch (cursorType & CursorTypeBitMask) {
+ case 0x0802:
+ return QTabletEvent::Stylus;
+ case 0x0902:
+ return QTabletEvent::Airbrush;
+ case 0x0004:
+ return QTabletEvent::FourDMouse;
+ case 0x0006:
+ return QTabletEvent::Puck;
+ case 0x0804:
+ return QTabletEvent::RotationStylus;
+ default:
+ break;
+ }
+ return QTabletEvent::NoDevice;
+}
+
+static inline QTabletEvent::PointerType pointerType(unsigned currentCursor)
+{
+ switch (currentCursor % 3) { // %3 for dual track
+ case 0:
+ return QTabletEvent::Cursor;
+ case 1:
+ return QTabletEvent::Pen;
+ case 2:
+ return QTabletEvent::Eraser;
+ default:
+ break;
+ }
+ return QTabletEvent::UnknownPointer;
+}
+
+QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t)
+{
+ d << "TabletDevice id:" << t.uniqueId << " pressure: " << t.minPressure
+ << ".." << t.maxPressure << " tan pressure: " << t.minTanPressure << ".."
+ << t.maxTanPressure << " area:" << t.minX << t.minY <<t.minZ
+ << ".." << t.maxX << t.maxY << t.maxZ << " device " << t.currentDevice
+ << " pointer " << t.currentPointerType;
+ return d;
+}
+
+QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueId, const UINT cursorType) const
+{
+ QWindowsTabletDeviceData result;
+ result.uniqueId = uniqueId;
+ /* browse WinTab's many info items to discover pressure handling. */
+ AXIS axis;
+ LOGCONTEXT lc;
+ /* get the current context for its device variable. */
+ QWindowsTabletSupport::m_winTab32DLL.wTGet(m_context, &lc);
+ /* get the size of the pressure axis. */
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &axis);
+ result.minPressure = int(axis.axMin);
+ result.maxPressure = int(axis.axMax);
+
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &axis);
+ result.minTanPressure = int(axis.axMin);
+ result.maxTanPressure = int(axis.axMax);
+
+ LOGCONTEXT defaultLc;
+ /* get default region */
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFCONTEXT, 0, &defaultLc);
+ result.maxX = int(defaultLc.lcInExtX) - int(defaultLc.lcInOrgX);
+ result.maxY = int(defaultLc.lcInExtY) - int(defaultLc.lcInOrgY);
+ result.maxZ = int(defaultLc.lcInExtZ) - int(defaultLc.lcInOrgZ);
+ result.currentDevice = deviceType(cursorType);
+ return result;
+}
+
+bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
+{
+ const bool enteredProximity = LOWORD(lParam) != 0;
+ PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
+ const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
+ if (!totalPacks)
+ return false;
+ const UINT currentCursor = proximityBuffer[0].pkCursor;
+ UINT physicalCursorId;
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
+ UINT cursorType;
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &cursorType);
+ const qint64 uniqueId = (qint64(cursorType & DeviceIdMask) << 32L) | qint64(physicalCursorId);
+ // initializing and updating the cursor should be done in response to
+ // WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send
+ // the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES
+ m_currentDevice = indexOfDevice(m_devices, uniqueId);
+ if (m_currentDevice < 0) {
+ m_currentDevice = m_devices.size();
+ m_devices.push_back(tabletInit(uniqueId, cursorType));
+ }
+ m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << (enteredProximity ? "enter" : "leave")
+ << " proximity for device #"
+ << m_currentDevice << m_devices.at(m_currentDevice);
+ if (enteredProximity) {
+ QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ m_devices.at(m_currentDevice).currentPointerType,
+ m_devices.at(m_currentDevice).uniqueId);
+ } else {
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ m_devices.at(m_currentDevice).currentPointerType,
+ m_devices.at(m_currentDevice).uniqueId);
+ }
+ return true;
+}
+
+bool QWindowsTabletSupport::translateTabletPacketEvent()
+{
+ static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue.
+ const int packetCount = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, TabletPacketQSize, &localPacketBuf);
+ if (!packetCount || m_currentDevice < 0)
+ return false;
+
+ const int currentDevice = m_devices.at(m_currentDevice).currentDevice;
+ const int currentPointer = m_devices.at(m_currentDevice).currentPointerType;
+
+ // When entering proximity, the tablet driver snaps the mouse pointer to the
+ // tablet position scaled to the virtual desktop and keeps it in sync.
+ const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
+
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << "processing " << packetCount
+ << "target:" << QGuiApplicationPrivate::tabletPressTarget;
+
+ const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+
+ for (int i = 0; i < packetCount ; ++i) {
+ const PACKET &packet = localPacketBuf[i];
+
+ const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0;
+ const QPointF globalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
+
+ QWindow *target = QGuiApplicationPrivate::tabletPressTarget; // Pass to window that grabbed it.
+ const QPoint globalPos = globalPosF.toPoint();
+ if (!target)
+ if (QPlatformWindow *pw = QWindowsContext::instance()->findPlatformWindowAt(GetDesktopWindow(), globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT))
+ target = pw->window();
+ if (!target)
+ continue;
+
+ const QPoint localPos = target->mapFromGlobal(globalPos);
+
+ const qreal pressureNew = packet.pkButtons && (currentPointer == QTabletEvent::Pen || currentPointer == QTabletEvent::Eraser) ?
+ m_devices.at(m_currentDevice).scalePressure(packet.pkNormalPressure) :
+ qreal(0);
+ const qreal tangentialPressure = currentDevice == QTabletEvent::Airbrush ?
+ m_devices.at(m_currentDevice).scaleTangentialPressure(packet.pkTangentPressure) :
+ qreal(0);
+
+ int tiltX = 0;
+ int tiltY = 0;
+ qreal rotation = 0;
+ if (m_tiltSupport) {
+ // Convert from azimuth and altitude to x tilt and y tilt. What
+ // follows is the optimized version. Here are the equations used:
+ // X = sin(azimuth) * cos(altitude)
+ // Y = cos(azimuth) * cos(altitude)
+ // Z = sin(altitude)
+ // X Tilt = arctan(X / Z)
+ // Y Tilt = arctan(Y / Z)
+ const double radAzim = (packet.pkOrientation.orAzimuth / 10) * (M_PI / 180);
+ const double tanAlt = tan((abs(packet.pkOrientation.orAltitude / 10)) * (M_PI / 180));
+
+ const double degX = atan(sin(radAzim) / tanAlt);
+ const double degY = atan(cos(radAzim) / tanAlt);
+ tiltX = int(degX * (180 / M_PI));
+ tiltY = int(-degY * (180 / M_PI));
+ rotation = packet.pkOrientation.orTwist;
+ }
+
+ if (QWindowsContext::verboseTablet > 1) {
+ qDebug()
+ << "Packet #" << i << '/' << packetCount << "button:" << packet.pkButtons
+ << globalPosF << z << "to:" << target << localPos << "(packet" << packet.pkX
+ << packet.pkY << ") dev:" << currentDevice << "pointer:"
+ << currentPointer << "P:" << pressureNew << "tilt:" << tiltX << ','
+ << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
+ }
+
+ QWindowSystemInterface::handleTabletEvent(target, packet.pkButtons, localPos, globalPosF,
+ currentDevice, currentPointer,
+ pressureNew, tiltX, tiltY,
+ tangentialPressure, rotation, z,
+ m_devices.at(m_currentDevice).uniqueId,
+ keyboardModifiers);
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TABLETEVENT
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
new file mode 100644
index 0000000000..12f96b618d
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSTABLETSUPPORT_H
+#define QWINDOWSTABLETSUPPORT_H
+
+#include "qtwindowsglobal.h"
+
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+
+#include <QtCore/QVector>
+#include <QtCore/QPointF>
+
+#include <wintab.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+class QWindow;
+class QRect;
+
+struct QWindowsWinTab32DLL
+{
+ QWindowsWinTab32DLL() : wTOpen(0), wTClose(0), wTInfo(0), wTEnable(0), wTOverlap(0), wTPacketsGet(0), wTGet(0),
+ wTQueueSizeGet(0), wTQueueSizeSet(0) {}
+
+ bool init();
+
+ typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
+ typedef BOOL (API *PtrWTClose)(HCTX);
+ typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID);
+ typedef BOOL (API *PtrWTEnable)(HCTX, BOOL);
+ typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL);
+ typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID);
+ typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
+ typedef int (API *PtrWTQueueSizeGet)(HCTX);
+ typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
+
+ PtrWTOpen wTOpen;
+ PtrWTClose wTClose;
+ PtrWTInfo wTInfo;
+ PtrWTEnable wTEnable;
+ PtrWTOverlap wTOverlap;
+ PtrWTPacketsGet wTPacketsGet;
+ PtrWTGet wTGet;
+ PtrWTQueueSizeGet wTQueueSizeGet;
+ PtrWTQueueSizeSet wTQueueSizeSet;
+};
+
+struct QWindowsTabletDeviceData
+{
+ QWindowsTabletDeviceData() : minPressure(0), maxPressure(0), minTanPressure(0),
+ maxTanPressure(0), minX(0), maxX(0), minY(0), maxY(0), minZ(0), maxZ(0),
+ uniqueId(0), currentDevice(0), currentPointerType(0) {}
+
+ QPointF scaleCoordinates(int coordX, int coordY,const QRect &targetArea) const;
+ qreal scalePressure(qreal p) const { return p / qreal(maxPressure - minPressure); }
+ qreal scaleTangentialPressure(qreal p) const { return p / qreal(maxTanPressure - minTanPressure); }
+
+ int minPressure;
+ int maxPressure;
+ int minTanPressure;
+ int maxTanPressure;
+ int minX, maxX, minY, maxY, minZ, maxZ;
+ qint64 uniqueId;
+ int currentDevice;
+ int currentPointerType;
+};
+
+QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t);
+
+class QWindowsTabletSupport
+{
+ Q_DISABLE_COPY(QWindowsTabletSupport)
+
+ explicit QWindowsTabletSupport(HWND window, HCTX context);
+
+public:
+ ~QWindowsTabletSupport();
+
+ static QWindowsTabletSupport *create();
+
+ void notifyActivate();
+ QString description() const;
+
+ bool translateTabletProximityEvent(WPARAM wParam, LPARAM lParam);
+ bool translateTabletPacketEvent();
+
+private:
+ unsigned options() const;
+ QWindowsTabletDeviceData tabletInit(const quint64 uniqueId, const UINT cursorType) const;
+
+ static QWindowsWinTab32DLL m_winTab32DLL;
+ const HWND m_window;
+ const HCTX m_context;
+ bool m_tiltSupport;
+ QVector<QWindowsTabletDeviceData> m_devices;
+ int m_currentDevice;
+};
+
+QT_END_NAMESPACE
+
+#endif // !QT_NO_TABLETEVENT && !Q_OS_WINCE
+#endif // QWINDOWSTABLETSUPPORT_H
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 9f6e6b18e7..49fdfc15b8 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -54,6 +54,11 @@
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
# include "winuser.h"
+#else
+# include <commctrl.h>
+# include <objbase.h>
+# include <commoncontrols.h>
+# include <shellapi.h>
#endif
#include <QtCore/QVariant>
@@ -69,6 +74,12 @@
#include <qpa/qwindowsysteminterface.h>
#include <private/qsystemlibrary_p.h>
+#include <algorithm>
+
+#if defined(__IImageList_INTERFACE_DEFINED__) && defined(__IID_DEFINED__)
+# define USE_IIMAGELIST
+#endif
+
QT_BEGIN_NAMESPACE
static inline QTextStream& operator<<(QTextStream &str, const QColor &c)
@@ -290,8 +301,8 @@ QWindowsTheme *QWindowsTheme::m_instance = 0;
QWindowsTheme::QWindowsTheme()
{
m_instance = this;
- qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
- qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+ std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
+ std::fill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
refresh();
}
@@ -361,8 +372,15 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
case IconPixmapSizes: {
QList<int> sizes;
sizes << 16 << 32;
+#ifdef USE_IIMAGELIST
+ sizes << 48; // sHIL_EXTRALARGE
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
+ sizes << 256; // SHIL_JUMBO
+#endif // USE_IIMAGELIST
return QVariant::fromValue(sizes);
}
+ case DialogSnapToDefaultButton:
+ return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false));
default:
break;
}
@@ -372,7 +390,7 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
void QWindowsTheme::clearPalettes()
{
qDeleteAll(m_palettes, m_palettes + NPalettes);
- qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+ std::fill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
}
void QWindowsTheme::refreshPalettes()
@@ -393,7 +411,7 @@ void QWindowsTheme::refreshPalettes()
void QWindowsTheme::clearFonts()
{
qDeleteAll(m_fonts, m_fonts + NFonts);
- qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
+ std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
}
void QWindowsTheme::refreshFonts()
@@ -410,6 +428,8 @@ void QWindowsTheme::refreshFonts()
const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont);
const QFont titleFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfCaptionFont);
+ QFont fixedFont(QStringLiteral("Courier New"), messageBoxFont.pointSize());
+ fixedFont.setStyleHint(QFont::TypeWriter);
LOGFONT lfIconTitleFont;
SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
@@ -424,6 +444,7 @@ void QWindowsTheme::refreshFonts()
m_fonts[MdiSubWindowTitleFont] = new QFont(titleFont);
m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
m_fonts[ItemViewFont] = new QFont(iconTitleFont);
+ m_fonts[FixedFont] = new QFont(fixedFont);
if (QWindowsContext::verboseTheming)
qDebug() << __FUNCTION__ << '\n'
@@ -573,11 +594,24 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
return QPlatformTheme::standardPixmap(sp, size);
}
-static QString dirIconPixmapCacheKey(int iIcon, int iconSize)
+enum { // Shell image list ids
+ sHIL_EXTRALARGE = 0x2, // 48x48 or user-defined
+ sHIL_JUMBO = 0x4 // 256x256 (Vista or later)
+};
+
+static QString dirIconPixmapCacheKey(int iIcon, int iconSize, int imageListSize)
{
QString key = QLatin1String("qt_dir_") + QString::number(iIcon);
if (iconSize == SHGFI_LARGEICON)
key += QLatin1Char('l');
+ switch (imageListSize) {
+ case sHIL_EXTRALARGE:
+ key += QLatin1Char('e');
+ break;
+ case sHIL_JUMBO:
+ key += QLatin1Char('j');
+ break;
+ }
return key;
}
@@ -601,7 +635,40 @@ public:
void operator delete (void *) {}
};
-QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
+// Shell image list helper functions.
+
+static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
+{
+ QPixmap result;
+#ifdef USE_IIMAGELIST
+ // For MinGW:
+ static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}};
+
+ if (!QWindowsContext::shell32dll.sHGetImageList)
+ return result;
+ if (iImageList == sHIL_JUMBO && QSysInfo::WindowsVersion < QSysInfo::WV_VISTA)
+ return result;
+
+ IImageList *imageList = 0;
+ HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList, (void **)&imageList);
+ if (hr != S_OK)
+ return result;
+ HICON hIcon;
+ hr = imageList->GetIcon(info.iIcon, ILD_TRANSPARENT, &hIcon);
+ if (hr == S_OK) {
+ result = qt_pixmapFromWinHICON(hIcon);
+ DestroyIcon(hIcon);
+ }
+ imageList->Release();
+#else
+ Q_UNUSED(iImageList)
+ Q_UNUSED(info)
+#endif // USE_IIMAGELIST
+ return result;
+}
+
+QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions) const
{
/* We don't use the variable, but by storing it statically, we
* ensure CoInitialize is only called once. */
@@ -610,17 +677,26 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
static QCache<QString, FakePointer<int> > dirIconEntryCache(1000);
static QMutex mx;
+ static int defaultFolderIIcon = 0;
+ const bool useDefaultFolderIcon = iconOptions & QPlatformTheme::DontUseCustomDirectoryIcons;
QPixmap pixmap;
const QString filePath = QDir::toNativeSeparators(fileInfo.filePath());
- int iconSize = size.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
-
+ const int width = size.width();
+ const int iconSize = width > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
+ const int requestedImageListSize =
+#ifdef USE_IIMAGELIST
+ width > 48 ? sHIL_JUMBO : (width > 32 ? sHIL_EXTRALARGE : 0);
+#else
+ 0;
+#endif // !USE_IIMAGELIST
bool cacheableDirIcon = fileInfo.isDir() && !fileInfo.isRoot();
if (cacheableDirIcon) {
QMutexLocker locker(&mx);
- int iIcon = **dirIconEntryCache.object(filePath);
+ int iIcon = (useDefaultFolderIcon && defaultFolderIIcon) ? defaultFolderIIcon
+ : **dirIconEntryCache.object(filePath);
if (iIcon) {
- QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize), pixmap);
+ QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize), pixmap);
if (pixmap.isNull()) // Let's keep both caches in sync
dirIconEntryCache.remove(filePath);
else
@@ -635,15 +711,26 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
#else
iconSize|SHGFI_SYSICONINDEX;
#endif // Q_OS_WINCE
- unsigned long val = SHGetFileInfo((const wchar_t *)filePath.utf16(), 0,
- &info, sizeof(SHFILEINFO), flags);
+ unsigned long val = 0;
+ if (cacheableDirIcon && useDefaultFolderIcon) {
+ flags |= SHGFI_USEFILEATTRIBUTES;
+ val = SHGetFileInfo(L"dummy",
+ FILE_ATTRIBUTE_DIRECTORY,
+ &info, sizeof(SHFILEINFO), flags);
+ } else {
+ val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
+ &info, sizeof(SHFILEINFO), flags);
+ }
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
if (val && info.hIcon) {
QString key;
if (cacheableDirIcon) {
+ if (useDefaultFolderIcon && !defaultFolderIIcon)
+ defaultFolderIIcon = info.iIcon;
+
//using the unique icon index provided by windows save us from duplicate keys
- key = dirIconPixmapCacheKey(info.iIcon, iconSize);
+ key = dirIconPixmapCacheKey(info.iIcon, iconSize, requestedImageListSize);
QPixmapCache::find(key, pixmap);
if (!pixmap.isNull()) {
QMutexLocker locker(&mx);
@@ -652,7 +739,13 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
}
if (pixmap.isNull()) {
- pixmap = qt_pixmapFromWinHICON(info.hIcon);
+ if (requestedImageListSize) {
+ pixmap = pixmapFromShellImageList(requestedImageListSize, info);
+ if (pixmap.isNull() && requestedImageListSize == sHIL_JUMBO)
+ pixmap = pixmapFromShellImageList(sHIL_EXTRALARGE, info);
+ }
+ if (pixmap.isNull())
+ pixmap = qt_pixmapFromWinHICON(info.hIcon);
if (!pixmap.isNull()) {
if (cacheableDirIcon) {
QMutexLocker locker(&mx);
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index bbd7f4623f..9346621d59 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -68,7 +68,8 @@ public:
{ return m_fonts[type]; }
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
- virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
+ virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions = 0) const;
void windowsThemeChanged(QWindow *window);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index ace18ddf5b..f3faccbc14 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -56,6 +56,7 @@
#include <QtGui/QScreen>
#include <QtGui/QWindow>
#include <QtGui/QRegion>
+#include <private/qsystemlibrary_p.h>
#include <private/qwindow_p.h>
#include <private/qguiapplication_p.h>
#include <qpa/qwindowsysteminterface.h>
@@ -203,6 +204,69 @@ static inline QSize clientSize(HWND hwnd)
return qSizeOfRect(rect);
}
+static bool applyBlurBehindWindow(HWND hwnd)
+{
+#ifdef Q_OS_WINCE
+ Q_UNUSED(hwnd);
+ return false;
+#else
+ enum { dwmBbEnable = 0x1, dwmBbBlurRegion = 0x2 };
+
+ struct DwmBlurBehind {
+ DWORD dwFlags;
+ BOOL fEnable;
+ HRGN hRgnBlur;
+ BOOL fTransitionOnMaximized;
+ };
+
+ typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND, const DwmBlurBehind*);
+ typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL *);
+
+ // DWM API is available only from Windows Vista
+ if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
+ return false;
+
+ static bool functionPointersResolved = false;
+ static PtrDwmEnableBlurBehindWindow dwmBlurBehind = 0;
+ static PtrDwmIsCompositionEnabled dwmIsCompositionEnabled = 0;
+
+ if (Q_UNLIKELY(!functionPointersResolved)) {
+ QSystemLibrary library(QStringLiteral("dwmapi"));
+ if (library.load()) {
+ dwmBlurBehind = (PtrDwmEnableBlurBehindWindow)(library.resolve("DwmEnableBlurBehindWindow"));
+ dwmIsCompositionEnabled = (PtrDwmIsCompositionEnabled)(library.resolve("DwmIsCompositionEnabled"));
+ }
+
+ functionPointersResolved = true;
+ }
+
+ if (Q_UNLIKELY(!dwmBlurBehind || !dwmIsCompositionEnabled))
+ return false;
+
+ BOOL compositionEnabled;
+ if (dwmIsCompositionEnabled(&compositionEnabled) != S_OK)
+ return false;
+
+ DwmBlurBehind blurBehind = {0, 0, 0, 0};
+
+ if (compositionEnabled) {
+ blurBehind.dwFlags = dwmBbEnable | dwmBbBlurRegion;
+ blurBehind.fEnable = TRUE;
+ blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
+ } else {
+ blurBehind.dwFlags = dwmBbEnable;
+ blurBehind.fEnable = FALSE;
+ }
+
+ const bool result = dwmBlurBehind(hwnd, &blurBehind) == S_OK;
+
+ if (blurBehind.hRgnBlur)
+ DeleteObject(blurBehind.hRgnBlur);
+
+ return result;
+#endif // Q_OS_WINCE
+}
+
// from qwidget_win.cpp, pass flags separately in case they have been "autofixed".
static bool shouldShowMaximizeButton(const QWindow *w, Qt::WindowFlags flags)
{
@@ -543,6 +607,10 @@ QWindowsWindow::WindowData
result.frame = context->margins;
result.embedded = embedded;
result.customMargins = context->customMargins;
+
+ if (isGL && hasAlpha)
+ applyBlurBehindWindow(result.hwnd);
+
return result;
}
@@ -1167,6 +1235,13 @@ void QWindowsWindow::handleHidden()
fireExpose(QRegion());
}
+void QWindowsWindow::handleCompositionSettingsChanged()
+{
+ const QWindow *w = window();
+ if (w->surfaceType() == QWindow::OpenGLSurface && w->format().hasAlpha())
+ applyBlurBehindWindow(handle());
+}
+
void QWindowsWindow::setGeometry(const QRect &rectIn)
{
QRect rect = rectIn;
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index afcfa8b821..f055864482 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -221,6 +221,7 @@ public:
void handleMoved();
void handleResized(int wParam);
void handleHidden();
+ void handleCompositionSettingsChanged();
static inline HWND handleOf(const QWindow *w);
static inline QWindowsWindow *baseWindowOf(const QWindow *w);
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index 3aa9caaa0f..d4e6e558ed 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -102,6 +102,12 @@ contains(QT_CONFIG, opengles2) {
}
}
+!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) {
+ INCLUDEPATH += ../../../3rdparty/wintab
+ HEADERS += qwindowstabletsupport.h
+ SOURCES += qwindowstabletsupport.cpp
+}
+
contains(QT_CONFIG, freetype) {
DEFINES *= QT_NO_FONTCONFIG
QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/main.cpp
index be5a0e3501..e114827703 100644
--- a/src/plugins/platforms/xcb/main.cpp
+++ b/src/plugins/platforms/xcb/main.cpp
@@ -47,15 +47,15 @@ QT_BEGIN_NAMESPACE
class QXcbIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "xcb.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "xcb.json")
public:
- QPlatformIntegration *create(const QString&, const QStringList&);
+ QPlatformIntegration *create(const QString&, const QStringList&, int &, char **);
};
-QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters)
+QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv)
{
if (system.toLower() == "xcb")
- return new QXcbIntegration(parameters);
+ return new QXcbIntegration(parameters, argc, argv);
return 0;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 2ce34ea8f2..ff5b36c448 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -51,13 +51,15 @@
#include "qxcbwmsupport.h"
#include "qxcbnativeinterface.h"
#include "qxcbintegration.h"
+#include "qxcbsystemtraytracker.h"
-#include <QtAlgorithms>
#include <QSocketNotifier>
#include <QAbstractEventDispatcher>
#include <QTimer>
#include <QByteArray>
+#include <algorithm>
+
#include <dlfcn.h>
#include <stdio.h>
#include <errno.h>
@@ -262,6 +264,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
, has_xkb(false)
, m_buttons(0)
, m_focusWindow(0)
+ , m_systemTrayTracker(0)
{
#ifdef XCB_USE_XLIB
Display *dpy = XOpenDisplay(m_displayName.constData());
@@ -656,6 +659,11 @@ void QXcbConnection::log(const char *file, int line, int sequence)
void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
{
+ long result = 0;
+ QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
+ if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), error, &result))
+ return;
+
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
@@ -813,6 +821,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
case XCB_UNMAP_NOTIFY:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
+ case XCB_DESTROY_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent);
case XCB_CLIENT_MESSAGE:
handleClientMessageEvent((xcb_client_message_event_t *)event);
break;
@@ -1196,6 +1206,8 @@ void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *
drag()->handleFinished(event);
}
#endif
+ if (m_systemTrayTracker && event->type == atom(QXcbAtom::MANAGER))
+ m_systemTrayTracker->notifyManagerClientMessageEvent(event);
QXcbWindow *window = platformWindowFromId(event->window);
if (!window)
@@ -1231,6 +1243,8 @@ static const char * xcb_atomnames = {
"_NET_WM_CONTEXT_HELP\0"
"_NET_WM_SYNC_REQUEST\0"
"_NET_WM_SYNC_REQUEST_COUNTER\0"
+ "MANAGER\0"
+ "_NET_SYSTEM_TRAY_OPCODE\0"
// ICCCM window state
"WM_STATE\0"
@@ -1388,6 +1402,8 @@ static const char * xcb_atomnames = {
"Abs MT Pressure\0"
"Abs MT Tracking ID\0"
"Max Contacts\0"
+ "Rel X\0"
+ "Rel Y\0"
// XInput2 tablet
"Abs X\0"
"Abs Y\0"
@@ -1404,9 +1420,9 @@ static const char * xcb_atomnames = {
"_XSETTINGS_SETTINGS\0" // \0\0 terminates loop.
};
-xcb_atom_t QXcbConnection::atom(QXcbAtom::Atom atom)
+QXcbAtom::Atom QXcbConnection::qatom(xcb_atom_t xatom) const
{
- return m_allAtoms[atom];
+ return static_cast<QXcbAtom::Atom>(std::find(m_allAtoms, m_allAtoms + QXcbAtom::NAtoms, xatom) - m_allAtoms);
}
void QXcbConnection::initializeAllAtoms() {
@@ -1724,6 +1740,17 @@ bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int o
}
#endif // defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
+QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker()
+{
+ if (!m_systemTrayTracker) {
+ if ( (m_systemTrayTracker = QXcbSystemTrayTracker::create(this)) ) {
+ connect(m_systemTrayTracker, SIGNAL(systemTrayWindowChanged(QScreen*)),
+ QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)));
+ }
+ }
+ return m_systemTrayTracker;
+}
+
QXcbConnectionGrabber::QXcbConnectionGrabber(QXcbConnection *connection)
:m_connection(connection)
{
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 2a5ff0b1cb..7cabe67a68 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -87,6 +87,7 @@ class QXcbKeyboard;
class QXcbClipboard;
class QXcbWMSupport;
class QXcbNativeInterface;
+class QXcbSystemTrayTracker;
namespace QXcbAtom {
enum Atom {
@@ -98,6 +99,8 @@ namespace QXcbAtom {
_NET_WM_CONTEXT_HELP,
_NET_WM_SYNC_REQUEST,
_NET_WM_SYNC_REQUEST_COUNTER,
+ MANAGER, // System tray notification
+ _NET_SYSTEM_TRAY_OPCODE, // System tray operation
// ICCCM window state
WM_STATE,
@@ -256,6 +259,8 @@ namespace QXcbAtom {
AbsMTPressure,
AbsMTTrackingID,
MaxContacts,
+ RelX,
+ RelY,
// XInput2 tablet
AbsX,
AbsY,
@@ -319,6 +324,7 @@ public:
virtual void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *) {}
virtual void handleMapNotifyEvent(const xcb_map_notify_event_t *) {}
virtual void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *) {}
+ virtual void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *) {}
virtual void handleButtonPressEvent(const xcb_button_press_event_t *) {}
virtual void handleButtonReleaseEvent(const xcb_button_release_event_t *) {}
virtual void handleMotionNotifyEvent(const xcb_motion_notify_event_t *) {}
@@ -346,7 +352,8 @@ public:
const QList<QXcbScreen *> &screens() const { return m_screens; }
int primaryScreen() const { return m_primaryScreen; }
- xcb_atom_t atom(QXcbAtom::Atom atom);
+ inline xcb_atom_t atom(QXcbAtom::Atom atom) const { return m_allAtoms[atom]; }
+ QXcbAtom::Atom qatom(xcb_atom_t atom) const;
xcb_atom_t internAtom(const char *name);
QByteArray atomName(xcb_atom_t atom);
@@ -430,6 +437,9 @@ public:
void ungrabServer();
QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; }
+
+ QXcbSystemTrayTracker *systemTrayTracker();
+
private slots:
void processXcbEvents();
@@ -478,8 +488,6 @@ private:
};
QHash<int, ValuatorClassInfo> valuatorInfo;
};
- void xi2QueryTabletData(void *dev, TabletData *tabletData); // use no XI stuff in headers
- void xi2SetupTabletDevices();
bool xi2HandleTabletEvent(void *event, TabletData *tabletData);
void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
QVector<TabletData> m_tabletData;
@@ -565,6 +573,7 @@ private:
QXcbWindow *m_focusWindow;
QByteArray m_startupId;
+ QXcbSystemTrayTracker *m_systemTrayTracker;
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 799bb387e1..b144d953a7 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -44,8 +44,8 @@
#include "qxcbwindow.h"
#include "qtouchdevice.h"
#include <qpa/qwindowsysteminterface.h>
-//#define XI2_TOUCH_DEBUG
-#ifdef XI2_TOUCH_DEBUG
+//#define XI2_DEBUG
+#ifdef XI2_DEBUG
#include <QDebug>
#endif
@@ -63,20 +63,19 @@ struct XInput2DeviceData {
}
XIDeviceInfo *xiDeviceInfo;
QTouchDevice *qtTouchDevice;
-};
-#ifndef QT_NO_TABLETEVENT
-static inline bool q_xi2_is_tablet(XIDeviceInfo *dev)
-{
- QByteArray name(dev->name);
- name = name.toLower();
- // Cannot just check for "wacom" because that would also pick up the touch and tablet-button devices.
- return name.contains("stylus") || name.contains("eraser");
-}
-#endif // QT_NO_TABLETEVENT
+ // Stuff that is relevant only for touchpads
+ QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed
+ QPointF firstPressedPosition; // in screen coordinates where the first point was pressed
+ QPointF firstPressedNormalPosition; // device coordinates (0 to 1, 0 to 1) where the first point was pressed
+ QSizeF size; // device size in mm
+};
void QXcbConnection::initializeXInput2()
{
+#ifndef QT_NO_TABLETEVENT
+ m_tabletData.clear();
+#endif
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
@@ -88,13 +87,78 @@ void QXcbConnection::initializeXInput2()
m_xi2Enabled = true;
}
if (m_xi2Enabled) {
+#ifdef XI2_DEBUG
+ qDebug("XInput version %d.%d is supported", xiMajor, m_xi2Minor);
+#endif
+ int deviceCount = 0;
+ XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
+ for (int i = 0; i < deviceCount; ++i) {
+ // Only non-master pointing devices are relevant here.
+ if (devices[i].use != XISlavePointer)
+ continue;
+#ifdef XI2_DEBUG
+ qDebug() << "input device "<< devices[i].name;
+#endif
#ifndef QT_NO_TABLETEVENT
- // Tablet support: Find the stylus-related devices.
- xi2SetupTabletDevices();
+ TabletData tabletData;
+#endif
+ for (int c = 0; c < devices[i].num_classes; ++c) {
+ switch (devices[i].classes[c]->type) {
+ case XIValuatorClass: {
+ XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(devices[i].classes[c]);
+ const int valuatorAtom = qatom(vci->label);
+#ifdef XI2_DEBUG
+ qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
+#endif
+#ifndef QT_NO_TABLETEVENT
+ if (valuatorAtom < QXcbAtom::NAtoms) {
+ TabletData::ValuatorClassInfo info;
+ info.minVal = vci->min;
+ info.maxVal = vci->max;
+ info.number = vci->number;
+ tabletData.valuatorInfo[valuatorAtom] = info;
+ }
#endif // QT_NO_TABLETEVENT
-#ifdef XI2_TOUCH_DEBUG
- qDebug("XInput version %d.%d is supported", xiMajor, m_xi2Minor);
+ } break;
+ default:
+ break;
+ }
+ }
+ bool isTablet = false;
+#ifndef QT_NO_TABLETEVENT
+ // If we have found the valuators which we expect a tablet to have, assume it's a tablet.
+ if (tabletData.valuatorInfo.contains(QXcbAtom::AbsX) &&
+ tabletData.valuatorInfo.contains(QXcbAtom::AbsY) &&
+ tabletData.valuatorInfo.contains(QXcbAtom::AbsPressure)) {
+ tabletData.deviceId = devices[i].deviceid;
+ tabletData.pointerType = QTabletEvent::Pen;
+ if (QByteArray(devices[i].name).toLower().contains("eraser"))
+ tabletData.pointerType = QTabletEvent::Eraser;
+ m_tabletData.append(tabletData);
+ isTablet = true;
+#ifdef XI2_DEBUG
+ qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
#endif
+ }
+#endif // QT_NO_TABLETEVENT
+ if (!isTablet) {
+ XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
+#ifdef XI2_DEBUG
+ if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
+ qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
+ dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
+ dev->qtTouchDevice->maximumTouchPoints());
+ else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
+ qDebug(" it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
+ dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
+ dev->qtTouchDevice->maximumTouchPoints(),
+ dev->size.width(), dev->size.height());
+#else
+ Q_UNUSED(dev);
+#endif // XI2_DEBUG
+ }
+ }
+ XIFreeDeviceInfo(devices);
}
}
}
@@ -113,25 +177,24 @@ void QXcbConnection::xi2Select(xcb_window_t window)
unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask);
#ifdef XCB_USE_XINPUT22
- // Select touch events on all master devices indiscriminately.
bitMask |= XI_TouchBeginMask;
bitMask |= XI_TouchUpdateMask;
bitMask |= XI_TouchEndMask;
XIEventMask mask;
- mask.deviceid = XIAllMasterDevices;
mask.mask_len = sizeof(bitMask);
mask.mask = xiBitMask;
- Status result = XISelectEvents(xDisplay, window, &mask, 1);
- // If we have XInput 2.2 and successfully enable touch on the master
- // devices, then evdev touchscreens will provide touch only. In most other
- // cases, there will be emulated mouse events, because true X11 touch
- // support is so new that for the older drivers, mouse emulation was the
- // only way; and it's still the fallback even with the modern evdev driver.
- // But if neither Qt nor X11 does mouse emulation, it will not be possible
- // to interact with mouse-oriented QWidgets; so we have to let Qt do it.
- if (m_xi2Minor >= 2 && result == Success)
- has_touch_without_mouse_emulation = true;
-#endif
+ // Enable each touchscreen
+ foreach (XInput2DeviceData *dev, m_touchDevices.values()) {
+ mask.deviceid = dev->xiDeviceInfo->deviceid;
+ Status result = XISelectEvents(xDisplay, window, &mask, 1);
+ // If we have XInput >= 2.2 and successfully enable a touchscreen, then
+ // it will provide touch only. In most other cases, there will be
+ // emulated mouse events from the driver. If not, then Qt must do its
+ // own mouse emulation to enable interaction with mouse-oriented QWidgets.
+ if (m_xi2Minor >= 2 && result == Success)
+ has_touch_without_mouse_emulation = true;
+ }
+#endif // XCB_USE_XINPUT22
#ifndef QT_NO_TABLETEVENT
// For each tablet, select some additional event types.
@@ -163,23 +226,29 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
QTouchDevice::Capabilities caps = 0;
dev = new XInput2DeviceData;
dev->xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), id, &unused);
- dev->qtTouchDevice = new QTouchDevice;
+ int type = -1;
+ int maxTouchPoints = 1;
+ bool hasRelativeCoords = false;
for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) {
XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i];
switch (classinfo->type) {
#ifdef XCB_USE_XINPUT22
case XITouchClass: {
XITouchClassInfo *tci = reinterpret_cast<XITouchClassInfo *>(classinfo);
+ maxTouchPoints = tci->num_touches;
+#ifdef XI2_DEBUG
+ qDebug(" has touch class with mode %d", tci->mode);
+#endif
switch (tci->mode) {
case XIModeRelative:
- dev->qtTouchDevice->setType(QTouchDevice::TouchPad);
+ type = QTouchDevice::TouchPad;
break;
case XIModeAbsolute:
- dev->qtTouchDevice->setType(QTouchDevice::TouchScreen);
+ type = QTouchDevice::TouchScreen;
break;
}
} break;
-#endif
+#endif // XCB_USE_XINPUT22
case XIValuatorClass: {
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo);
if (vci->label == atom(QXcbAtom::AbsMTPositionX))
@@ -188,18 +257,36 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
caps |= QTouchDevice::Area;
else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure))
caps |= QTouchDevice::Pressure;
+ else if (vci->label == atom(QXcbAtom::RelX)) {
+ hasRelativeCoords = true;
+ dev->size.setWidth((vci->max - vci->min) * 1000.0 / vci->resolution);
+ } else if (vci->label == atom(QXcbAtom::RelY)) {
+ hasRelativeCoords = true;
+ dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution);
+ }
} break;
}
}
- dev->qtTouchDevice->setCapabilities(caps);
- dev->qtTouchDevice->setName(dev->xiDeviceInfo->name);
- if (caps != 0)
- QWindowSystemInterface::registerTouchDevice(dev->qtTouchDevice);
-#ifdef XI2_TOUCH_DEBUG
- qDebug("registered new device %s with %d classes and %d max touch points",
- dev->xiDeviceInfo->name, dev->xiDeviceInfo->num_classes, dev->qtTouchDevice->maxTouchPoints());
-#endif
- m_touchDevices[id] = dev;
+ if (type < 0 && caps && hasRelativeCoords) {
+ type = QTouchDevice::TouchPad;
+ if (dev->size.width() < 10 || dev->size.height() < 10 ||
+ dev->size.width() > 10000 || dev->size.height() > 10000)
+ dev->size = QSizeF(130, 110);
+ }
+ if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) {
+ dev->qtTouchDevice = new QTouchDevice;
+ dev->qtTouchDevice->setName(dev->xiDeviceInfo->name);
+ dev->qtTouchDevice->setType((QTouchDevice::DeviceType)type);
+ dev->qtTouchDevice->setCapabilities(caps);
+ dev->qtTouchDevice->setMaximumTouchPoints(maxTouchPoints);
+ if (caps != 0)
+ QWindowSystemInterface::registerTouchDevice(dev->qtTouchDevice);
+ m_touchDevices[id] = dev;
+ } else {
+ m_touchDevices.remove(id);
+ delete dev;
+ dev = 0;
+ }
}
return dev;
}
@@ -218,7 +305,7 @@ static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
value = vci->min;
return (value - vci->min) / (vci->max - vci->min);
}
-#endif
+#endif // XCB_USE_XINPUT22
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
@@ -237,7 +324,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
#ifdef XCB_USE_XINPUT22
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
-#ifdef XI2_TOUCH_DEBUG
+#ifdef XI2_DEBUG
qDebug("XI2 event type %d seq %d detail %d pos 0x%X,0x%X %f,%f root pos %f,%f",
event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail,
xiDeviceEvent->event_x, xiDeviceEvent->event_y,
@@ -247,6 +334,8 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
XInput2DeviceData *dev = deviceForId(xiEvent->deviceid);
+ Q_ASSERT(dev);
+ const bool firstTouch = m_touchPoints.isEmpty();
if (xiEvent->evtype == XI_TouchBegin) {
QWindowSystemInterface::TouchPoint tp;
tp.id = xiDeviceEvent->detail % INT_MAX;
@@ -267,11 +356,15 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
double value;
if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value))
continue;
-#ifdef XI2_TOUCH_DEBUG
- qDebug(" valuator class label %d value %lf from range %lf -> %lf name %s",
- vci->label, value, vci->min, vci->max, XGetAtomName(static_cast<Display *>(m_xlib_display), vci->label) );
+#ifdef XI2_DEBUG
+ qDebug(" valuator %20s value %lf from range %lf -> %lf",
+ atomName(vci->label).constData(), value, vci->min, vci->max );
#endif
- if (vci->label == atom(QXcbAtom::AbsMTPositionX)) {
+ if (vci->label == atom(QXcbAtom::RelX)) {
+ nx = valuatorNormalized(value, vci);
+ } else if (vci->label == atom(QXcbAtom::RelY)) {
+ ny = valuatorNormalized(value, vci);
+ } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) {
nx = valuatorNormalized(value, vci);
} else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) {
ny = valuatorNormalized(value, vci);
@@ -306,17 +399,43 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
switch (xiEvent->evtype) {
+ case XI_TouchBegin:
+ if (firstTouch) {
+ dev->firstPressedPosition = QPointF(x, y);
+ dev->firstPressedNormalPosition = QPointF(nx, ny);
+ }
+ dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y));
+ break;
case XI_TouchUpdate:
- if (touchPoint.area.center() != QPoint(x, y))
+ if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
+ qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
+ dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
+ qreal dy = (ny - dev->firstPressedNormalPosition.y()) *
+ dev->size.height() * screen->geometry().height() / screen->physicalSize().height();
+ x = dev->firstPressedPosition.x() + dx;
+ y = dev->firstPressedPosition.y() + dy;
+ touchPoint.state = Qt::TouchPointMoved;
+ } else if (touchPoint.area.center() != QPoint(x, y)) {
touchPoint.state = Qt::TouchPointMoved;
+ dev->pointPressedPosition[touchPoint.id] = QPointF(x, y);
+ }
break;
case XI_TouchEnd:
touchPoint.state = Qt::TouchPointReleased;
+ if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
+ qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
+ dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
+ qreal dy = (ny - dev->firstPressedNormalPosition.y()) *
+ dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
+ x = dev->firstPressedPosition.x() + dx;
+ y = dev->firstPressedPosition.y() + dy;
+ }
+ dev->pointPressedPosition.remove(touchPoint.id);
}
touchPoint.area = QRectF(x - w/2, y - h/2, w, h);
touchPoint.normalPosition = QPointF(nx, ny);
-#ifdef XI2_TOUCH_DEBUG
+#ifdef XI2_DEBUG
qDebug() << " tp " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition <<
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
#endif
@@ -330,80 +449,11 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
touchPoint.state = Qt::TouchPointStationary;
}
}
-#endif
+#endif // XCB_USE_XINPUT22
}
}
#ifndef QT_NO_TABLETEVENT
-void QXcbConnection::xi2QueryTabletData(void *dev, TabletData *tabletData)
-{
- XIDeviceInfo *device = static_cast<XIDeviceInfo *>(dev);
- tabletData->deviceId = device->deviceid;
-
- tabletData->pointerType = QTabletEvent::Pen;
- if (QByteArray(device->name).toLower().contains("eraser"))
- tabletData->pointerType = QTabletEvent::Eraser;
-
- for (int i = 0; i < device->num_classes; ++i) {
- switch (device->classes[i]->type) {
- case XIValuatorClass: {
- XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(device->classes[i]);
- int val = 0;
- if (vci->label == atom(QXcbAtom::AbsX))
- val = QXcbAtom::AbsX;
- else if (vci->label == atom(QXcbAtom::AbsY))
- val = QXcbAtom::AbsY;
- else if (vci->label == atom(QXcbAtom::AbsPressure))
- val = QXcbAtom::AbsPressure;
- else if (vci->label == atom(QXcbAtom::AbsTiltX))
- val = QXcbAtom::AbsTiltX;
- else if (vci->label == atom(QXcbAtom::AbsTiltY))
- val = QXcbAtom::AbsTiltY;
- else if (vci->label == atom(QXcbAtom::AbsWheel))
- val = QXcbAtom::AbsWheel;
- else if (vci->label == atom(QXcbAtom::AbsDistance))
- val = QXcbAtom::AbsDistance;
- if (val) {
- TabletData::ValuatorClassInfo info;
- info.minVal = vci->min;
- info.maxVal = vci->max;
- info.number = vci->number;
- tabletData->valuatorInfo[val] = info;
- }
- }
- break;
- default:
- break;
- }
- }
-}
-
-void QXcbConnection::xi2SetupTabletDevices()
-{
- Display *xDisplay = static_cast<Display *>(m_xlib_display);
- m_tabletData.clear();
- int deviceCount = 0;
- XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
- if (devices) {
- for (int i = 0; i < deviceCount; ++i) {
- int unused = 0;
- XIDeviceInfo *dev = XIQueryDevice(xDisplay, devices[i].deviceid, &unused);
- if (dev) {
- if (q_xi2_is_tablet(dev)) {
- TabletData tabletData;
- xi2QueryTabletData(dev, &tabletData);
-#ifdef XI2_TOUCH_DEBUG
- qDebug() << "found tablet" << dev->name;
-#endif
- m_tabletData.append(tabletData);
- }
- XIFreeDeviceInfo(dev);
- }
- }
- XIFreeDeviceInfo(devices);
- }
-}
-
bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
{
bool handled = true;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index cf7e99023a..68ad93143b 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -119,9 +119,10 @@ static bool runningUnderDebugger()
}
#endif
-QXcbIntegration::QXcbIntegration(const QStringList &parameters)
+QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char **argv)
: m_eventDispatcher(createUnixEventDispatcher())
, m_services(new QGenericUnixServices)
+ , m_instanceName(0)
{
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
@@ -138,7 +139,28 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters)
if (canNotGrabEnv)
canGrab = false;
- m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab);
+ // Parse arguments
+ const char *displayName = 0;
+ if (argc) {
+ int j = 1;
+ for (int i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (arg) {
+ if (!strcmp(arg, "-display") && i < argc - 1) {
+ displayName = argv[++i];
+ arg = 0;
+ } else if (!strcmp(arg, "-name") && i < argc - 1) {
+ m_instanceName = argv[++i];
+ arg = 0;
+ }
+ }
+ if (arg)
+ argv[j++] = arg;
+ }
+ argc = j;
+ } // argc
+
+ m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab, displayName);
for (int i = 0; i < parameters.size() - 1; i += 2) {
#ifdef Q_XCB_DEBUG
@@ -365,6 +387,8 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
// We do not want Qt to synthesize mouse events if X11 already does it.
return m_connections.at(0)->hasTouchWithoutMouseEmulation();
+ default:
+ break;
}
return QPlatformIntegration::styleHint(hint);
}
@@ -389,6 +413,8 @@ QByteArray QXcbIntegration::wmClass() const
if (m_wmClass.isEmpty()) {
// Instance name according to ICCCM 4.1.2.5
QString name;
+ if (m_instanceName)
+ name = QString::fromLocal8Bit(m_instanceName);
if (name.isEmpty() && qEnvironmentVariableIsSet(resourceNameVar))
name = QString::fromLocal8Bit(qgetenv(resourceNameVar));
if (name.isEmpty())
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 07b6b8d678..09fc0d32b5 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -55,7 +55,7 @@ class QXcbScreen;
class QXcbIntegration : public QPlatformIntegration
{
public:
- QXcbIntegration(const QStringList &parameters);
+ QXcbIntegration(const QStringList &parameters, int &argc, char **argv);
~QXcbIntegration();
QPlatformWindow *createPlatformWindow(QWindow *window) const;
@@ -119,6 +119,7 @@ private:
friend class QXcbConnection; // access QPlatformIntegration::screenAdded()
mutable QByteArray m_wmClass;
+ const char *m_instanceName;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index d1729ed168..2529fb8a83 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -243,6 +243,10 @@
#define XF86XK_Select 0x1008FFA0
#define XF86XK_View 0x1008FFA1
#define XF86XK_TopMenu 0x1008FFA2
+#define XF86XK_Red 0x1008FFA3
+#define XF86XK_Green 0x1008FFA4
+#define XF86XK_Yellow 0x1008FFA5
+#define XF86XK_Blue 0x1008FFA6
#define XF86XK_Suspend 0x1008FFA7
#define XF86XK_Hibernate 0x1008FFA8
#define XF86XK_TouchpadToggle 0x1008FFA9
@@ -538,6 +542,10 @@ static const unsigned int KeyTbl[] = {
XF86XK_Select, Qt::Key_Select,
XF86XK_View, Qt::Key_View,
XF86XK_TopMenu, Qt::Key_TopMenu,
+ XF86XK_Red, Qt::Key_Red,
+ XF86XK_Green, Qt::Key_Green,
+ XF86XK_Yellow, Qt::Key_Yellow,
+ XF86XK_Blue, Qt::Key_Blue,
XF86XK_Bluetooth, Qt::Key_Bluetooth,
XF86XK_Suspend, Qt::Key_Suspend,
XF86XK_Hibernate, Qt::Key_Hibernate,
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 9e9fd2914f..99e9932847 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -42,7 +42,9 @@
#include "qxcbnativeinterface.h"
#include "qxcbscreen.h"
+#include "qxcbwindow.h"
#include "qxcbintegration.h"
+#include "qxcbsystemtraytracker.h"
#include <private/qguiapplication_p.h>
#include <QtCore/QMap>
@@ -82,6 +84,8 @@ public:
insert("appusertime",QXcbNativeInterface::AppUserTime);
insert("hintstyle", QXcbNativeInterface::ScreenHintStyle);
insert("startupid", QXcbNativeInterface::StartupId);
+ insert(QByteArrayLiteral("traywindow"), QXcbNativeInterface::TrayWindow);
+ insert(QByteArrayLiteral("gettimestamp"), QXcbNativeInterface::GetTimestamp);
}
};
@@ -100,6 +104,36 @@ void QXcbNativeInterface::beep() // For QApplication::beep()
xcb_bell(connection, 0);
}
+static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s)
+{
+ return static_cast<const QXcbScreen *>(s->handle())->connection()->systemTrayTracker();
+}
+
+bool QXcbNativeInterface::systemTrayAvailable(const QScreen *screen) const
+{
+ return systemTrayTracker(screen);
+}
+
+bool QXcbNativeInterface::requestSystemTrayWindowDock(const QWindow *window)
+{
+ const QPlatformWindow *platformWindow = window->handle();
+ if (!platformWindow)
+ return false;
+ QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen());
+ if (!trayTracker)
+ return false;
+ trayTracker->requestSystemTrayWindowDock(static_cast<const QXcbWindow *>(platformWindow)->xcb_window());
+ return true;
+}
+
+QRect QXcbNativeInterface::systemTrayWindowGlobalGeometry(const QWindow *window)
+{
+ if (const QPlatformWindow *platformWindow = window->handle())
+ if (const QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen()))
+ return trayTracker->systemTrayWindowGlobalGeometry(static_cast<const QXcbWindow *>(platformWindow)->xcb_window());
+ return QRect();
+}
+
void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
{
QByteArray lowerCaseResource = resourceString.toLower();
@@ -162,6 +196,14 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
break;
case ScreenHintStyle:
result = reinterpret_cast<void *>(xcbScreen->hintStyle() + 1);
+ break;
+ case TrayWindow:
+ if (QXcbSystemTrayTracker *s = systemTrayTracker(screen))
+ result = (void *)quintptr(s->trayWindow());
+ break;
+ case GetTimestamp:
+ result = getTimestamp(xcbScreen);
+ break;
default:
break;
}
@@ -216,6 +258,11 @@ void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen)
return reinterpret_cast<void *>(quintptr(screen->connection()->netWmUserTime()));
}
+void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen)
+{
+ return reinterpret_cast<void *>(quintptr(screen->connection()->getTimestamp()));
+}
+
void *QXcbNativeInterface::startupId()
{
QXcbIntegration* integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index e27bfa5a46..86b94e62e4 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -45,6 +45,8 @@
#include <qpa/qplatformnativeinterface.h>
#include <xcb/xcb.h>
+#include <QtCore/QRect>
+
QT_BEGIN_NAMESPACE
class QWidget;
@@ -66,7 +68,9 @@ public:
AppTime,
AppUserTime,
ScreenHintStyle,
- StartupId
+ StartupId,
+ TrayWindow,
+ GetTimestamp
};
QXcbNativeInterface();
@@ -88,6 +92,7 @@ public:
void *graphicsDeviceForWindow(QWindow *window);
void *appTime(const QXcbScreen *screen);
void *appUserTime(const QXcbScreen *screen);
+ void *getTimestamp(const QXcbScreen *screen);
void *startupId();
static void setAppTime(QScreen *screen, xcb_timestamp_t time);
static void setAppUserTime(QScreen *screen, xcb_timestamp_t time);
@@ -95,6 +100,12 @@ public:
static void *glxContextForContext(QOpenGLContext *context);
Q_INVOKABLE void beep();
+ Q_INVOKABLE bool systemTrayAvailable(const QScreen *screen) const;
+ Q_INVOKABLE bool requestSystemTrayWindowDock(const QWindow *window);
+ Q_INVOKABLE QRect systemTrayWindowGlobalGeometry(const QWindow *window);
+
+signals:
+ void systemTrayWindowChanged(QScreen *screen);
private:
const QByteArray m_genericEventFilterType;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 37c6c97bc4..6961a2fd79 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -112,6 +112,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW
| XCB_EVENT_MASK_PROPERTY_CHANGE
+ | XCB_EVENT_MASK_STRUCTURE_NOTIFY // for the "MANAGER" atom (system tray notification).
};
xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values);
@@ -148,7 +149,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
if (!sync_reply || !sync_reply->present)
m_syncRequestSupported = false;
else
- m_syncRequestSupported = m_windowManagerName != QLatin1String("KWin");
+ m_syncRequestSupported = true;
m_clientLeader = xcb_generate_id(xcb_connection());
Q_XCB_CALL2(xcb_create_window(xcb_connection(),
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
new file mode 100644
index 0000000000..24d2feb106
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbsystemtraytracker.h"
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QRect>
+#include <QtGui/QScreen>
+
+#include <qpa/qplatformnativeinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ SystemTrayRequestDock = 0,
+ SystemTrayBeginMessage = 1,
+ SystemTrayCancelMessage = 2
+};
+
+// QXcbSystemTrayTracker provides API for accessing the tray window and tracks
+// its lifecyle by listening for its destruction and recreation.
+// See http://standards.freedesktop.org/systemtray-spec/systemtray-spec-latest.html
+
+QXcbSystemTrayTracker *QXcbSystemTrayTracker::create(QXcbConnection *connection)
+{
+ // Selection, tray atoms for GNOME, NET WM Specification
+ const xcb_atom_t trayAtom = connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_OPCODE);
+ if (!trayAtom)
+ return 0;
+ const QByteArray netSysTray = QByteArrayLiteral("_NET_SYSTEM_TRAY_S") + QByteArray::number(connection->primaryScreen());
+ const xcb_atom_t selection = connection->internAtom(netSysTray.constData());
+ if (!selection)
+ return 0;
+ return new QXcbSystemTrayTracker(connection, trayAtom, selection, connection);
+}
+
+QXcbSystemTrayTracker::QXcbSystemTrayTracker(QXcbConnection *connection,
+ xcb_atom_t trayAtom,
+ xcb_atom_t selection,
+ QObject *parent)
+ : QObject(parent)
+ , m_selection(selection)
+ , m_trayAtom(trayAtom)
+ , m_connection(connection)
+ , m_trayWindow(0)
+{
+}
+
+xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection)
+{
+ xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(connection->xcb_connection(), selection);
+ xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(connection->xcb_connection(), cookie, 0);
+ if (!reply)
+ return 0;
+ const xcb_window_t result = reply->owner;
+ free(reply);
+ return result;
+}
+
+// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Request a window
+// to be docked on the tray.
+void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const
+{
+ xcb_client_message_event_t trayRequest;
+ memset(&trayRequest, 0, sizeof(trayRequest));
+ trayRequest.response_type = XCB_CLIENT_MESSAGE;
+ trayRequest.format = 32;
+ trayRequest.window = m_trayWindow;
+ trayRequest.type = m_trayAtom;
+ trayRequest.data.data32[0] = XCB_CURRENT_TIME;
+ trayRequest.data.data32[1] = SystemTrayRequestDock;
+ trayRequest.data.data32[2] = window;
+ xcb_send_event(m_connection->xcb_connection(), 0, m_trayWindow, XCB_EVENT_MASK_NO_EVENT, (const char *)&trayRequest);
+}
+
+// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Return tray window.
+xcb_window_t QXcbSystemTrayTracker::trayWindow()
+{
+ if (!m_trayWindow) {
+ m_trayWindow = QXcbSystemTrayTracker::locateTrayWindow(m_connection, m_selection);
+ if (m_trayWindow) { // Listen for DestroyNotify on tray.
+ m_connection->addWindowEventListener(m_trayWindow, this);
+ const quint32 mask = XCB_CW_EVENT_MASK;
+ const quint32 value = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+ Q_XCB_CALL(xcb_change_window_attributes(m_connection->xcb_connection(), m_trayWindow, mask, &value));
+ }
+ }
+ return m_trayWindow;
+}
+
+// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Return the geometry of a
+// a window parented on the tray. Determines the global geometry via XCB since mapToGlobal
+// does not work for the QWindow parented on the tray.
+QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const
+{
+ xcb_connection_t *conn = m_connection->xcb_connection();
+ xcb_get_geometry_reply_t *geomReply =
+ xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), 0);
+ if (!geomReply)
+ return QRect();
+
+ xcb_translate_coordinates_reply_t *translateReply =
+ xcb_translate_coordinates_reply(conn, xcb_translate_coordinates(conn, window, m_connection->rootWindow(), 0, 0), 0);
+ if (!translateReply) {
+ free(geomReply);
+ return QRect();
+ }
+
+ const QRect result(QPoint(translateReply->dst_x, translateReply->dst_y), QSize(geomReply->width, geomReply->height));
+ free(translateReply);
+ return result;
+}
+
+inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged()
+{
+ const int screen = m_connection->primaryScreen();
+ if (screen >= 0 && screen < m_connection->screens().size()) {
+ const QPlatformScreen *ps = m_connection->screens().at(screen);
+ emit systemTrayWindowChanged(ps->screen());
+ }
+}
+
+// Client messages with the "MANAGER" atom on the root window indicate creation of a new tray.
+void QXcbSystemTrayTracker::notifyManagerClientMessageEvent(const xcb_client_message_event_t *t)
+{
+ if (t->data.data32[1] == m_selection)
+ emitSystemTrayWindowChanged();
+}
+
+// Listen for destruction of the tray.
+void QXcbSystemTrayTracker::handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *event)
+{
+ if (event->window == m_trayWindow) {
+ m_connection->removeWindowEventListener(m_trayWindow);
+ m_trayWindow = 0;
+ emitSystemTrayWindowChanged();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
new file mode 100644
index 0000000000..c6b0a0659e
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBSYSTEMTRAYTRACKER_H
+#define QXCBSYSTEMTRAYTRACKER_H
+
+#include "qxcbconnection.h"
+
+#include <xcb/xcb.h>
+
+QT_BEGIN_NAMESPACE
+
+class QXcbConnection;
+class QScreen;
+
+class QXcbSystemTrayTracker : public QObject, public QXcbWindowEventListener
+{
+ Q_OBJECT
+public:
+ static QXcbSystemTrayTracker *create(QXcbConnection *connection);
+
+ xcb_window_t trayWindow();
+ void requestSystemTrayWindowDock(xcb_window_t window) const;
+ QRect systemTrayWindowGlobalGeometry(xcb_window_t window) const;
+
+ void notifyManagerClientMessageEvent(const xcb_client_message_event_t *);
+
+ void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *);
+
+signals:
+ void systemTrayWindowChanged(QScreen *screen);
+
+private:
+ explicit QXcbSystemTrayTracker(QXcbConnection *connection,
+ xcb_atom_t trayAtom,
+ xcb_atom_t selection,
+ QObject *parent = 0);
+ static xcb_window_t locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection);
+ void emitSystemTrayWindowChanged();
+
+ const xcb_atom_t m_selection;
+ const xcb_atom_t m_trayAtom;
+ QXcbConnection *m_connection;
+ xcb_window_t m_trayWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QXCBSYSTEMTRAYTRACKER_H
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 028cd9ab72..46c3fdce5c 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -57,6 +57,8 @@
#include <qpa/qplatformintegration.h>
+#include <algorithm>
+
// FIXME This workaround can be removed for xcb-icccm > 3.8
#define class class_name
#include <xcb/xcb_icccm.h>
@@ -152,7 +154,7 @@ enum QX11EmbedMessageType {
XEMBED_ACTIVATE_ACCELERATOR = 14
};
-static unsigned int XEMBED_VERSION = 0;
+const long XEMBED_VERSION = 0;
// Returns true if we should set WM_TRANSIENT_FOR on \a w
static inline bool isTransient(const QWindow *w)
@@ -779,21 +781,21 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) {
const xcb_atom_t *states = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply));
const xcb_atom_t *statesEnd = states + reply->length;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
result |= NetWmStateAbove;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_BELOW)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_BELOW)))
result |= NetWmStateBelow;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
result |= NetWmStateFullScreen;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
result |= NetWmStateMaximizedHorz;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)))
result |= NetWmStateMaximizedVert;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_MODAL)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_MODAL)))
result |= NetWmStateModal;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)))
result |= NetWmStateStaysOnTop;
- if (statesEnd != qFind(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
result |= NetWmStateDemandsAttention;
free(reply);
} else {
@@ -1502,6 +1504,9 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
} else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) {
connection()->setTime(event->data.data32[1]);
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
+ if (event->window == m_screen->root())
+ return;
+
xcb_client_message_event_t reply = *event;
reply.response_type = XCB_CLIENT_MESSAGE;
@@ -1515,8 +1520,7 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
m_syncValue.hi = event->data.data32[3];
#ifndef QT_NO_WHATSTHIS
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) {
- QEvent *e = new QEvent(QEvent::EnterWhatsThisMode);
- QGuiApplication::postEvent(QGuiApplication::instance(), e);
+ QWindowSystemInterface::handleEnterWhatsThisEvent();
#endif
} else {
qWarning() << "QXcbWindow: Unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]);
@@ -1533,6 +1537,11 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
#endif
} else if (event->type == atom(QXcbAtom::_XEMBED)) {
handleXEmbedMessage(event);
+ } else if (event->type == atom(QXcbAtom::MANAGER) || event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW)
+ || event->type == atom(QXcbAtom::_NET_WM_STATE) || event->type == atom(QXcbAtom::MANAGER)
+ || event->type == atom(QXcbAtom::WM_CHANGE_STATE)) {
+ // Ignore _NET_ACTIVE_WINDOW, _NET_WM_STATE, MANAGER which are relate to tray icons
+ // and other messages.
} else {
qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type);
}
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index 82995286c4..b198ab1717 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -21,7 +21,8 @@ SOURCES = \
qxcbnativeinterface.cpp \
qxcbcursor.cpp \
qxcbimage.cpp \
- qxcbxsettings.cpp
+ qxcbxsettings.cpp \
+ qxcbsystemtraytracker.cpp
HEADERS = \
qxcbclipboard.h \
@@ -38,7 +39,8 @@ HEADERS = \
qxcbnativeinterface.h \
qxcbcursor.h \
qxcbimage.h \
- qxcbxsettings.h
+ qxcbxsettings.h \
+ qxcbsystemtraytracker.h
LIBS += -ldl
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
index 91a23afac5..e8758da1c7 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
+++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
@@ -282,13 +282,13 @@ bool QGtk2FileDialogHelper::defaultNameFilterDisables() const
return false;
}
-void QGtk2FileDialogHelper::setDirectory(const QString &directory)
+void QGtk2FileDialogHelper::setDirectory(const QUrl &directory)
{
GtkDialog *gtkDialog = d->gtkDialog();
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), directory.toUtf8());
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), directory.toLocalFile().toUtf8());
}
-QString QGtk2FileDialogHelper::directory() const
+QUrl QGtk2FileDialogHelper::directory() const
{
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_current_folder()
// returns a bogus value -> return the cached value before hiding
@@ -302,27 +302,27 @@ QString QGtk2FileDialogHelper::directory() const
ret = QString::fromUtf8(folder);
g_free(folder);
}
- return ret;
+ return QUrl::fromLocalFile(ret);
}
-void QGtk2FileDialogHelper::selectFile(const QString &filename)
+void QGtk2FileDialogHelper::selectFile(const QUrl &filename)
{
GtkDialog *gtkDialog = d->gtkDialog();
- gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toUtf8());
+ gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toLocalFile().toUtf8());
}
-QStringList QGtk2FileDialogHelper::selectedFiles() const
+QList<QUrl> QGtk2FileDialogHelper::selectedFiles() const
{
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_filenames()
// returns a bogus value -> return the cached value before hiding
if (!_selection.isEmpty())
return _selection;
- QStringList selection;
+ QList<QUrl> selection;
GtkDialog *gtkDialog = d->gtkDialog();
GSList *filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(gtkDialog));
for (GSList *it = filenames; it; it = it->next)
- selection += QString::fromUtf8((const char*)it->data);
+ selection += QUrl::fromLocalFile(QString::fromUtf8((const char*)it->data));
g_slist_free(filenames);
return selection;
}
@@ -356,7 +356,7 @@ void QGtk2FileDialogHelper::onAccepted()
if (filter.isEmpty())
emit filterSelected(filter);
- QStringList files = selectedFiles();
+ QList<QUrl> files = selectedFiles();
emit filesSelected(files);
if (files.count() == 1)
emit fileSelected(files.first());
@@ -370,7 +370,7 @@ void QGtk2FileDialogHelper::onSelectionChanged(GtkDialog *gtkDialog, QGtk2FileDi
selection = QString::fromUtf8(filename);
g_free(filename);
}
- emit helper->currentChanged(selection);
+ emit helper->currentChanged(QUrl::fromLocalFile(selection));
}
void QGtk2FileDialogHelper::onCurrentFolderChanged(QGtk2FileDialogHelper *dialog)
@@ -419,12 +419,12 @@ void QGtk2FileDialogHelper::applyOptions()
if (!nameFilters.isEmpty())
setNameFilters(nameFilters);
- const QString initialDirectory = opts->initialDirectory();
+ const QString initialDirectory = opts->initialDirectory().toLocalFile();
if (!initialDirectory.isEmpty())
setDirectory(initialDirectory);
- foreach (const QString &filename, opts->initiallySelectedFiles())
- selectFile(filename);
+ foreach (const QUrl &filename, opts->initiallySelectedFiles())
+ selectFile(filename.toLocalFile());
const QString initialNameFilter = opts->initiallySelectedNameFilter();
if (!initialNameFilter.isEmpty())
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
index c2d12625f5..47a6153fbc 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
+++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
@@ -90,10 +90,10 @@ public:
void hide();
bool defaultNameFilterDisables() const;
- void setDirectory(const QString &directory);
- QString directory() const;
- void selectFile(const QString &filename);
- QStringList selectedFiles() const;
+ void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ QUrl directory() const Q_DECL_OVERRIDE;
+ void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
+ QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
void setFilter();
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
@@ -107,8 +107,8 @@ private:
void applyOptions();
void setNameFilters(const QStringList &filters);
- QString _dir;
- QStringList _selection;
+ QUrl _dir;
+ QList<QUrl> _selection;
QHash<QString, GtkFileFilter*> _filters;
QHash<GtkFileFilter*, QString> _filterNames;
QScopedPointer<QGtk2Dialog> d;
diff --git a/src/printsupport/doc/qtprintsupport.qdocconf b/src/printsupport/doc/qtprintsupport.qdocconf
index c7b14e16c1..d5015fa46a 100644
--- a/src/printsupport/doc/qtprintsupport.qdocconf
+++ b/src/printsupport/doc/qtprintsupport.qdocconf
@@ -40,3 +40,6 @@ excludedirs += ../../../examples/widgets/doc
imagedirs += images \
../../widgets/doc/images \
+
+navigation.landingpage = "Qt Print Support"
+navigation.cppclassespage = "Qt Print Support C++ Classes"
diff --git a/src/printsupport/doc/src/qtprintsupport-module.qdoc b/src/printsupport/doc/src/qtprintsupport-module.qdoc
index aaff476bc5..20ff11d8cb 100644
--- a/src/printsupport/doc/src/qtprintsupport-module.qdoc
+++ b/src/printsupport/doc/src/qtprintsupport-module.qdoc
@@ -31,6 +31,7 @@
\brief The Qt PrintSupport module provides classes to make printing easier and portable.
\ingroup modules
+ \qtvariable printsupport
To include the definitions of the module's classes, use the
following directive:
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index c798ac0c7f..36dd7ecb0c 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -89,7 +89,7 @@ static const struct {
{ DMPAPER_A5, QPrinter::A5 },
{ DMPAPER_B4, QPrinter::B4 },
{ DMPAPER_B5, QPrinter::B5 },
- { DMPAPER_FOLIO, QPrinter::Folio },
+ { DMPAPER_A4_PLUS, QPrinter::Folio },
{ DMPAPER_ENV_10, QPrinter::Comm10E },
{ DMPAPER_ENV_DL, QPrinter::DLE },
{ DMPAPER_ENV_C3, QPrinter::C5E },
@@ -103,7 +103,6 @@ static const struct {
{ DMPAPER_A_PLUS, QPrinter::A4 },
{ DMPAPER_B_PLUS, QPrinter::A3 },
{ DMPAPER_LETTER_PLUS, QPrinter::Letter },
- { DMPAPER_A4_PLUS, QPrinter::A4 },
{ DMPAPER_A5_TRANSVERSE, QPrinter::A5 },
{ DMPAPER_B5_TRANSVERSE, QPrinter::B5 },
{ DMPAPER_A3_EXTRA, QPrinter::A3 },
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index a8a99564ac..3e64582b06 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -388,6 +388,10 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke
With setFullPage(false) (the default), the metrics will be a bit
smaller; how much depends on the printer in use.
+ \note QPrinter::Folio is the Adobe specification for the Folio size.
+ On Windows if you want to use the same as DMPAPER_FOLIO then you should use
+ setPaperSize(QSizeF(8.5, 13), QPrinter::Inch).
+
\omitvalue NPageSize
\omitvalue NPaperSize
*/
diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf
index c2686079d5..a2a05d7c8a 100644
--- a/src/sql/doc/qtsql.qdocconf
+++ b/src/sql/doc/qtsql.qdocconf
@@ -39,3 +39,6 @@ exampledirs += ../../../examples/sql \
imagedirs += images \
../../../examples/sql/doc/images
+
+navigation.landingpage = "Qt SQL"
+navigation.cppclassespage = "Qt SQL C++ Classes"
diff --git a/src/sql/doc/src/qtsql.qdoc b/src/sql/doc/src/qtsql.qdoc
index 8ce981756a..2f806b4b45 100644
--- a/src/sql/doc/src/qtsql.qdoc
+++ b/src/sql/doc/src/qtsql.qdoc
@@ -62,6 +62,7 @@
\module QtSql
\title Qt SQL C++ Classes
\ingroup modules
+ \qtvariable sql
\brief Provides a driver layer, SQL API layer, and a user
interface layer for SQL databases.
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index e58710e0f5..d799060633 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -633,7 +633,7 @@ bool QDB2Result::exec()
dt->day = qdt.day();
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_DATE,
SQL_DATE,
0,
@@ -653,7 +653,7 @@ bool QDB2Result::exec()
dt->second = qdt.second();
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_TIME,
SQL_TIME,
0,
@@ -677,7 +677,7 @@ bool QDB2Result::exec()
dt->fraction = qdt.time().msec() * 1000000;
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_TIMESTAMP,
SQL_TIMESTAMP,
0,
@@ -690,7 +690,7 @@ bool QDB2Result::exec()
case QVariant::Int:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_SLONG,
SQL_INTEGER,
0,
@@ -702,7 +702,7 @@ bool QDB2Result::exec()
case QVariant::Double:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_DOUBLE,
SQL_DOUBLE,
0,
@@ -717,7 +717,7 @@ bool QDB2Result::exec()
*ind = len;
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_BINARY,
SQL_LONGVARBINARY,
len,
@@ -735,7 +735,7 @@ bool QDB2Result::exec()
QByteArray ba((char*)str.utf16(), str.capacity() * sizeof(QChar));
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_WCHAR,
SQL_WVARCHAR,
str.length(),
@@ -749,7 +749,7 @@ bool QDB2Result::exec()
int len = str.length();
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_WCHAR,
SQL_WVARCHAR,
len,
@@ -767,7 +767,7 @@ bool QDB2Result::exec()
*ind = ba.length();
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & 3],
+ qParamType[bindValueType(i) & 3],
SQL_C_CHAR,
SQL_VARCHAR,
len,
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 77accc6e9d..ac6d677d54 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -1349,7 +1349,7 @@ bool QODBCResult::exec()
dt->day = qdt.day();
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_DATE,
SQL_DATE,
0,
@@ -1369,7 +1369,7 @@ bool QODBCResult::exec()
dt->second = qdt.second();
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TIME,
SQL_TIME,
0,
@@ -1404,7 +1404,7 @@ bool QODBCResult::exec()
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TIMESTAMP,
SQL_TIMESTAMP,
d->driverPrivate->datetime_precision,
@@ -1417,7 +1417,7 @@ bool QODBCResult::exec()
case QVariant::Int:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_SLONG,
SQL_INTEGER,
0,
@@ -1429,7 +1429,7 @@ bool QODBCResult::exec()
case QVariant::UInt:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_ULONG,
SQL_NUMERIC,
15,
@@ -1441,7 +1441,7 @@ bool QODBCResult::exec()
case QVariant::Double:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_DOUBLE,
SQL_DOUBLE,
0,
@@ -1453,7 +1453,7 @@ bool QODBCResult::exec()
case QVariant::LongLong:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_SBIGINT,
SQL_BIGINT,
0,
@@ -1465,7 +1465,7 @@ bool QODBCResult::exec()
case QVariant::ULongLong:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_UBIGINT,
SQL_BIGINT,
0,
@@ -1480,7 +1480,7 @@ bool QODBCResult::exec()
}
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_BINARY,
SQL_LONGVARBINARY,
val.toByteArray().size(),
@@ -1492,7 +1492,7 @@ bool QODBCResult::exec()
case QVariant::Bool:
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_BIT,
SQL_BIT,
0,
@@ -1513,7 +1513,7 @@ bool QODBCResult::exec()
QByteArray ba((const char *)a.constData(), a.size() * sizeof(SQLTCHAR));
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TCHAR,
strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
0, // god knows... don't change this!
@@ -1527,7 +1527,7 @@ bool QODBCResult::exec()
QByteArray strba((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR));
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TCHAR,
strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
strSize,
@@ -1547,7 +1547,7 @@ bool QODBCResult::exec()
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_CHAR,
strSize > 254 ? SQL_LONGVARCHAR : SQL_VARCHAR,
strSize,
@@ -1565,7 +1565,7 @@ bool QODBCResult::exec()
*ind = ba.size();
r = SQLBindParameter(d->hStmt,
i + 1,
- qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
+ qParamType[bindValueType(i) & QSql::InOut],
SQL_C_BINARY,
SQL_VARBINARY,
ba.length() + 1,
diff --git a/src/src.pro b/src/src.pro
index 1c1c0e746e..c6ae533cff 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -102,12 +102,14 @@ src_android.subdir = $$PWD/android
# this order is important
SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc src_corelib
+TOOLS = src_tools_moc src_tools_rcc
win32:SUBDIRS += src_winmain
SUBDIRS += src_network src_sql src_xml src_testlib
contains(QT_CONFIG, dbus) {
SUBDIRS += src_dbus
force_bootstrap: SUBDIRS += src_tools_bootstrap_dbus
SUBDIRS += src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
+ TOOLS += src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
contains(QT_CONFIG, accessibility-atspi-bridge): \
src_platformsupport.depends += src_dbus src_tools_qdbusxml2cpp
src_plugins.depends += src_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
@@ -123,6 +125,7 @@ contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
src_plugins.depends += src_gui src_platformsupport
!contains(QT_CONFIG, no-widgets) {
SUBDIRS += src_tools_uic src_widgets
+ TOOLS += src_tools_uic
src_plugins.depends += src_widgets
contains(QT_CONFIG, opengl(es1|es2)?) {
SUBDIRS += src_opengl
@@ -143,3 +146,6 @@ android:!android-no-sdk: SUBDIRS += src_android
TR_EXCLUDE = \
src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic \
src_tools_bootstrap_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
+
+sub-tools.depends = $$TOOLS
+QMAKE_EXTRA_TARGETS = sub-tools \ No newline at end of file
diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf
index 2eea4f246a..ab2bdc1948 100644
--- a/src/testlib/doc/qttestlib.qdocconf
+++ b/src/testlib/doc/qttestlib.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/qtestlib \
excludedirs += ../../../examples/widgets/doc
imagedirs += images
+
+navigation.landingpage = "Qt Test"
+navigation.cppclassespage = "Qt Test C++ Classes"
diff --git a/src/testlib/doc/src/qttest.qdoc b/src/testlib/doc/src/qttest.qdoc
index 6e0bd3c070..c9e1683f83 100644
--- a/src/testlib/doc/src/qttest.qdoc
+++ b/src/testlib/doc/src/qttest.qdoc
@@ -29,6 +29,7 @@
\module QtTest
\title Qt Test C++ Classes
\ingroup modules
+ \qtvariable testlib
\keyword QtTest
diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc
index c44bb49ae3..613d2c220c 100644
--- a/src/testlib/doc/src/qttestlib-manual.qdoc
+++ b/src/testlib/doc/src/qttestlib-manual.qdoc
@@ -247,6 +247,9 @@
2000.
\li \c -nocrashhandler \br
Disables the crash handler on Unix platforms.
+ On Windows, it re-enables the Windows Error Reporting dialog, which is
+ turned off by default.
+
\li \c -platform \e name \br
This command line argument applies to all Qt applications, but might be
especially useful in the context of auto-testing. By using the "offscreen"
diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp
index d039c3c342..41f8f37872 100644
--- a/src/testlib/qabstracttestlogger.cpp
+++ b/src/testlib/qabstracttestlogger.cpp
@@ -52,6 +52,10 @@
#include <unistd.h>
#endif
+#ifdef Q_OS_ANDROID
+#include <sys/stat.h>
+#endif
+
QT_BEGIN_NAMESPACE
QAbstractTestLogger::QAbstractTestLogger(const char *filename)
@@ -69,6 +73,12 @@ QAbstractTestLogger::QAbstractTestLogger(const char *filename)
fprintf(stderr, "Unable to open file for logging: %s\n", filename);
::exit(1);
}
+#ifdef Q_OS_ANDROID
+ else {
+ // Make sure output is world-readable on Android
+ ::chmod(filename, 0666);
+ }
+#endif
}
QAbstractTestLogger::~QAbstractTestLogger()
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 77a59d0cf0..5d5a976201 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -1130,9 +1130,7 @@ namespace QTest
static int keyDelay = -1;
static int mouseDelay = -1;
static int eventDelay = -1;
-#if defined(Q_OS_UNIX)
static bool noCrashHandler = false;
-#endif
/*! \internal
Invoke a method of the object without generating warning if the method does not exist
@@ -1335,9 +1333,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
" -maxwarnings n : Sets the maximum amount of messages to output.\n"
" 0 means unlimited, default: 2000\n"
-#if defined(Q_OS_UNIX)
" -nocrashhandler : Disables the crash handler\n"
-#endif
"\n"
" Benchmarking options:\n"
#ifdef QTESTLIB_USE_VALGRIND
@@ -1468,10 +1464,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
} else {
QTestLog::setMaxWarnings(qToInt(argv[++i]));
}
-#if defined(Q_OS_UNIX)
} else if (strcmp(argv[i], "-nocrashhandler") == 0) {
QTest::noCrashHandler = true;
-#endif
#ifdef QTESTLIB_USE_VALGRIND
} else if (strcmp(argv[i], "-callgrind") == 0) {
if (QBenchmarkValgrindUtils::haveValgrind())
@@ -2083,6 +2077,18 @@ FatalSignalHandler::~FatalSignalHandler()
} // namespace
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo)
+{
+ char appName[MAX_PATH];
+ if (!GetModuleFileNameA(NULL, appName, MAX_PATH))
+ appName[0] = 0;
+ fprintf(stderr, "A crash occurred in %s (exception code 0x%lx).",
+ appName, exInfo->ExceptionRecord->ExceptionCode);
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif // Q_OS_WIN) && !Q_OS_WINCE
+
/*!
Executes tests declared in \a testObject. In addition, the private slots
\c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
@@ -2138,13 +2144,6 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
try {
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
-# if !defined(Q_CC_MINGW)
- _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
-# endif
- SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
-#endif
-
#if defined(Q_OS_MACX)
if (macNeedsActivate) {
CFStringRef reasonForActivity= CFSTR("No Display Sleep");
@@ -2170,6 +2169,16 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
qtest_qParseArgs(argc, argv, false);
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ if (!noCrashHandler) {
+# ifndef Q_CC_MINGW
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
+# endif
+ SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
+ SetUnhandledExceptionFilter(windowsFaultHandler);
+ } // !noCrashHandler
+#endif // Q_OS_WIN) && !Q_OS_WINCE
+
#ifdef QTESTLIB_USE_VALGRIND
if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
const QStringList origAppArgs(QCoreApplication::arguments());
diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp
index a6a8ee0cc1..7ab317f209 100644
--- a/src/testlib/qtestresult.cpp
+++ b/src/testlib/qtestresult.cpp
@@ -268,10 +268,12 @@ bool QTestResult::compare(bool success, const char *failureMsg,
if (success && QTest::expectFailMode) {
qsnprintf(msg, 1024, "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected);
} else if (val1 || val2) {
- qsnprintf(msg, 1024, "%s\n Actual (%s): %s\n Expected (%s): %s",
+ size_t len1 = strlen(actual);
+ size_t len2 = strlen(expected);
+ qsnprintf(msg, 1024, "%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s",
failureMsg,
- actual, val1 ? val1 : "<null>",
- expected, val2 ? val2 : "<null>");
+ actual, qMax(len1, len2) - len1 + 1, ":", val1 ? val1 : "<null>",
+ expected, qMax(len1, len2) - len2 + 1, ":", val2 ? val2 : "<null>");
} else
qsnprintf(msg, 1024, "%s", failureMsg);
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index 697c8f5574..dd5189758d 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -84,6 +84,8 @@ SOURCES += \
../../corelib/tools/qbytearray.cpp \
../../corelib/tools/qarraydata.cpp \
../../corelib/tools/qbytearraymatcher.cpp \
+ ../../corelib/tools/qcommandlineparser.cpp \
+ ../../corelib/tools/qcommandlineoption.cpp \
../../corelib/tools/qcryptographichash.cpp \
../../corelib/tools/qdatetime.cpp \
../../corelib/tools/qhash.cpp \
diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
index a66757907d..0e1fa59b90 100644
--- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -47,6 +47,7 @@
#include <qbuffer.h>
#include <qregexp.h>
#include <qvector.h>
+#include <qdebug.h>
#include <stdio.h>
#include <stdlib.h>
@@ -95,14 +96,14 @@ static const char help[] =
"\n";
-int qDBusParametersForMethod(const FunctionDef &mm, QVector<int>& metaTypes)
+int qDBusParametersForMethod(const FunctionDef &mm, QVector<int>& metaTypes, QString &errorMsg)
{
QList<QByteArray> parameterTypes;
foreach (const ArgumentDef &arg, mm.arguments)
parameterTypes.append(arg.normalizedType);
- return qDBusParametersForMethod(parameterTypes, metaTypes);
+ return qDBusParametersForMethod(parameterTypes, metaTypes, errorMsg);
}
@@ -140,9 +141,12 @@ static QString addFunction(const FunctionDef &mm, bool isSignal = false) {
}
QList<ArgumentDef> names = mm.arguments;
QVector<int> types;
- int inputCount = qDBusParametersForMethod(mm, types);
- if (inputCount == -1)
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
+ if (inputCount == -1) {
+ qWarning() << qPrintable(errorMsg);
return QString(); // invalid form
+ }
if (isSignal && inputCount + 1 != types.count())
return QString(); // signal with output arguments?
if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message())
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index e6d77643de..f2b9441ea4 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -401,6 +401,8 @@ static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs,
QString name = arg.name;
if (name.isEmpty())
name = QString( QLatin1String("in%1") ).arg(i);
+ else
+ name.replace(QLatin1Char('-'), QLatin1Char('_'));
while (retval.contains(name))
name += QLatin1String("_");
retval << name;
@@ -410,6 +412,8 @@ static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs,
QString name = arg.name;
if (name.isEmpty())
name = QString( QLatin1String("out%1") ).arg(i);
+ else
+ name.replace(QLatin1Char('-'), QLatin1Char('_'));
while (retval.contains(name))
name += QLatin1String("_");
retval << name;
diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp
index c7d9c5b339..8faac66b1b 100644
--- a/src/tools/qdoc/codemarker.cpp
+++ b/src/tools/qdoc/codemarker.cpp
@@ -398,7 +398,7 @@ void CodeMarker::insert(FastSection &fastSection,
bool inheritedMember = false;
if (!node->relates()) {
InnerNode* p = node->parent();
- if (p->subType() == Node::QmlPropertyGroup)
+ if (p->type() == Node::QmlPropertyGroup)
p = p->parent();
if (p != fastSection.parent_) { // && !node->parent()->isAbstract()) {
if (p->subType() != Node::QmlClass || !p->isAbstract()) {
diff --git a/src/tools/qdoc/codeparser.cpp b/src/tools/qdoc/codeparser.cpp
index 7b534a6c95..1be67894cc 100644
--- a/src/tools/qdoc/codeparser.cpp
+++ b/src/tools/qdoc/codeparser.cpp
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_PAGEKEYWORDS Doc::alias(QLatin1String("pagekeywords"))
#define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary"))
#define COMMAND_INPUBLICGROUP Doc::alias(QLatin1String("inpublicgroup"))
+#define COMMAND_QTVARIABLE Doc::alias(QLatin1String("qtvariable"))
#define COMMAND_REENTRANT Doc::alias(QLatin1String("reentrant"))
#define COMMAND_SINCE Doc::alias(QLatin1String("since"))
#define COMMAND_SUBTITLE Doc::alias(QLatin1String("subtitle"))
@@ -199,29 +200,34 @@ CodeParser *CodeParser::parserForSourceFile(const QString &filePath)
return 0;
}
+static QSet<QString> commonMetaCommands_;
/*!
Returns the set of strings representing the common metacommands.
*/
-QSet<QString> CodeParser::commonMetaCommands()
+const QSet<QString>& CodeParser::commonMetaCommands()
{
- return QSet<QString>() << COMMAND_COMPAT
- << COMMAND_DEPRECATED
- << COMMAND_INGROUP
- << COMMAND_INMODULE
- << COMMAND_INQMLMODULE
- << COMMAND_INTERNAL
- << COMMAND_MAINCLASS
- << COMMAND_NONREENTRANT
- << COMMAND_OBSOLETE
- << COMMAND_PAGEKEYWORDS
- << COMMAND_PRELIMINARY
- << COMMAND_INPUBLICGROUP
- << COMMAND_REENTRANT
- << COMMAND_SINCE
- << COMMAND_SUBTITLE
- << COMMAND_THREADSAFE
- << COMMAND_TITLE
- << COMMAND_WRAPPER;
+ if (commonMetaCommands_.isEmpty()) {
+ commonMetaCommands_ << COMMAND_COMPAT
+ << COMMAND_DEPRECATED
+ << COMMAND_INGROUP
+ << COMMAND_INMODULE
+ << COMMAND_INQMLMODULE
+ << COMMAND_INTERNAL
+ << COMMAND_MAINCLASS
+ << COMMAND_NONREENTRANT
+ << COMMAND_OBSOLETE
+ << COMMAND_PAGEKEYWORDS
+ << COMMAND_PRELIMINARY
+ << COMMAND_INPUBLICGROUP
+ << COMMAND_QTVARIABLE
+ << COMMAND_REENTRANT
+ << COMMAND_SINCE
+ << COMMAND_SUBTITLE
+ << COMMAND_THREADSAFE
+ << COMMAND_TITLE
+ << COMMAND_WRAPPER;
+ }
+ return commonMetaCommands_;
}
/*!
@@ -269,8 +275,8 @@ void CodeParser::processCommonMetaCommand(const Location& location,
if (!showInternal) {
node->setAccess(Node::Private);
node->setStatus(Node::Internal);
- if (node->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ if (node->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
@@ -317,6 +323,15 @@ void CodeParser::processCommonMetaCommand(const Location& location,
else
location.warning(tr("Ignored '\\%1'").arg(COMMAND_TITLE));
}
+ else if (command == COMMAND_QTVARIABLE) {
+ if (node->subType() == Node::Module) {
+ DocNode *dn = static_cast<DocNode *>(node);
+ dn->setQtVariable(arg.first);
+ }
+ else
+ location.warning(tr("Command '\\%1' found outside of '\\module'. It can only be used within a module page.")
+ .arg(COMMAND_QTVARIABLE));
+ }
}
/*!
diff --git a/src/tools/qdoc/codeparser.h b/src/tools/qdoc/codeparser.h
index 8c398aeb05..89f661abeb 100644
--- a/src/tools/qdoc/codeparser.h
+++ b/src/tools/qdoc/codeparser.h
@@ -86,7 +86,7 @@ public:
static const QString& currentOutputSubdirectory() { return currentSubDir_; }
protected:
- QSet<QString> commonMetaCommands();
+ const QSet<QString>& commonMetaCommands();
void processCommonMetaCommand(const Location& location,
const QString& command,
const ArgLocPair& arg,
diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp
index a475ccbfb6..48be30c24e 100644
--- a/src/tools/qdoc/config.cpp
+++ b/src/tools/qdoc/config.cpp
@@ -181,6 +181,7 @@ QSet<QString> Config::overrideOutputFormats;
QMap<QString, QString> Config::extractedDirs;
int Config::numInstances;
QStack<QString> Config::workingDirs_;
+QMap<QString, QStringList> Config::includeFilesMap_;
/*!
\class Config
@@ -201,6 +202,7 @@ Config::Config(const QString& programName)
lastLocation_ = Location::null;
configVars_.clear();
numInstances++;
+ includeFilesMap_.clear();
}
/*!
@@ -208,6 +210,7 @@ Config::Config(const QString& programName)
*/
Config::~Config()
{
+ includeFilesMap_.clear();
}
/*!
@@ -279,10 +282,19 @@ int Config::getInt(const QString& var) const
*/
QString Config::getOutputDir() const
{
+ QString t;
if (overrideOutputDir.isNull())
- return getString(QLatin1String(CONFIG_OUTPUTDIR));
+ t = getString(QLatin1String(CONFIG_OUTPUTDIR));
else
- return overrideOutputDir;
+ t = overrideOutputDir;
+ if (!Generator::useOutputSubdirs()) {
+ t = t.left(t.lastIndexOf('/'));
+ QString singleOutputSubdir = getString("HTML.outputsubdir");
+ if (singleOutputSubdir.isEmpty())
+ singleOutputSubdir = "html";
+ t += QLatin1Char('/') + singleOutputSubdir;
+ }
+ return t;
}
/*!
@@ -580,6 +592,33 @@ void Config::subVarsAndValues(const QString& var, ConfigVarMultimap& t) const
}
/*!
+ Get all .qdocinc files.
+ */
+QString Config::getIncludeFilePath(const QString& fileName) const
+{
+ QString ext = fileName.mid(fileName.lastIndexOf('.'));
+ ext.prepend('*');
+
+ if (!includeFilesMap_.contains(ext)) {
+ QSet<QString> t;
+ QStringList result;
+ QStringList dirs = getCanonicalPathList(CONFIG_SOURCEDIRS);
+ QStringList::ConstIterator d = dirs.constBegin();
+ while (d != dirs.constEnd()) {
+ result += getFilesHere(*d, ext, location(), t, t);
+ ++d;
+ }
+ includeFilesMap_.insert(ext, result);
+ }
+ const QStringList& paths = (*includeFilesMap_.find(ext));
+ for (int i=0; i<paths.size(); ++i) {
+ if (paths[i].endsWith(fileName))
+ return paths[i];
+ }
+ return QString();
+}
+
+/*!
Builds and returns a list of file pathnames for the file
type specified by \a filesVar (e.g. "headers" or "sources").
The files are found in the directories specified by
diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h
index 8787d27eb3..6efff44442 100644
--- a/src/tools/qdoc/config.h
+++ b/src/tools/qdoc/config.h
@@ -112,6 +112,7 @@ public:
const QString& dirsVar,
const QSet<QString> &excludedDirs = QSet<QString>(),
const QSet<QString> &excludedFiles = QSet<QString>());
+ QString getIncludeFilePath(const QString& fileName) const;
QStringList getExampleQdocFiles(const QSet<QString> &excludedDirs, const QSet<QString> &excludedFiles);
QStringList getExampleImageFiles(const QSet<QString> &excludedDirs, const QSet<QString> &excludedFiles);
@@ -160,12 +161,15 @@ private:
static QMap<QString, QString> extractedDirs;
static int numInstances;
static QStack<QString> workingDirs_;
+ static QMap<QString, QStringList> includeFilesMap_;
};
#define CONFIG_ALIAS "alias"
#define CONFIG_BASE "base"
#define CONFIG_BASEDIR "basedir"
+#define CONFIG_BUILDVERSION "buildversion"
#define CONFIG_CODEINDENT "codeindent"
+#define CONFIG_CPPCLASSESPAGE "cppclassespage"
#define CONFIG_DEFINES "defines"
#define CONFIG_DEPENDS "depends"
#define CONFIG_DESCRIPTION "description"
@@ -184,15 +188,18 @@ private:
#define CONFIG_HEADERS "headers"
#define CONFIG_HEADERSCRIPTS "headerscripts"
#define CONFIG_HEADERSTYLES "headerstyles"
+#define CONFIG_HOMEPAGE "homepage"
#define CONFIG_IGNOREDIRECTIVES "ignoredirectives"
#define CONFIG_IGNORETOKENS "ignoretokens"
#define CONFIG_IMAGEDIRS "imagedirs"
#define CONFIG_IMAGES "images"
#define CONFIG_INDEXES "indexes"
#define CONFIG_LANGUAGE "language"
+#define CONFIG_LANDINGPAGE "landingpage"
#define CONFIG_MACRO "macro"
#define CONFIG_MANIFESTMETA "manifestmeta"
#define CONFIG_NATURALLANGUAGE "naturallanguage"
+#define CONFIG_NAVIGATION "navigation"
#define CONFIG_NOLINKERRORS "nolinkerrors"
#define CONFIG_OBSOLETELINKS "obsoletelinks"
#define CONFIG_OUTPUTDIR "outputdir"
@@ -201,7 +208,9 @@ private:
#define CONFIG_OUTPUTFORMATS "outputformats"
#define CONFIG_OUTPUTPREFIXES "outputprefixes"
#define CONFIG_PROJECT "project"
+#define CONFIG_REDIRECTDOCUMENTATIONTODEVNULL "redirectdocumentationtodevnull"
#define CONFIG_QHP "qhp"
+#define CONFIG_QMLTYPESPAGE "qmltypespage"
#define CONFIG_QUOTINGINFORMATION "quotinginformation"
#define CONFIG_SCRIPTDIRS "scriptdirs"
#define CONFIG_SCRIPTS "scripts"
diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp
index 75e49f288a..ad3c5cba47 100644
--- a/src/tools/qdoc/cppcodemarker.cpp
+++ b/src/tools/qdoc/cppcodemarker.cpp
@@ -1110,40 +1110,15 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
while (qcn != 0) {
NodeList::ConstIterator c = qcn->childNodes().constBegin();
while (c != qcn->childNodes().constEnd()) {
- if ((*c)->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
- NodeList::ConstIterator p = qpgn->childNodes().constBegin();
- while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
- if (pn->isAttached())
- insert(qmlattachedproperties,*p,style,Okay);
- else
- insert(qmlproperties,*p,style,Okay);
- }
- ++p;
- }
+ if ((*c)->type() == Node::QmlPropertyGroup) {
+ insert(qmlproperties, *c, style, Okay);
}
else if ((*c)->type() == Node::QmlProperty) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
- if (pn->qmlPropNodes().isEmpty()) {
- if (pn->isAttached())
- insert(qmlattachedproperties,*c,style,Okay);
- else
- insert(qmlproperties,*c,style,Okay);
- }
+ if (pn->isAttached())
+ insert(qmlattachedproperties,*c,style,Okay);
else {
- NodeList::ConstIterator p = pn->qmlPropNodes().constBegin();
- while (p != pn->qmlPropNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
- if (pn->isAttached())
- insert(qmlattachedproperties,*p,style,Okay);
- else
- insert(qmlproperties,*p,style,Okay);
- }
- ++p;
- }
+ insert(qmlproperties,*c,style,Okay);
}
}
else if ((*c)->type() == Node::QmlSignal) {
@@ -1196,24 +1171,8 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
while (qcn != 0) {
NodeList::ConstIterator c = qcn->childNodes().constBegin();
while (c != qcn->childNodes().constEnd()) {
- if ((*c)->subType() == Node::QmlPropertyGroup) {
- bool attached = false;
- const QmlPropGroupNode* pgn = static_cast<const QmlPropGroupNode*>(*c);
- NodeList::ConstIterator C = pgn->childNodes().constBegin();
- while (C != pgn->childNodes().constEnd()) {
- if ((*C)->type() == Node::QmlProperty) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*C);
- if (pn->isAttached()) {
- attached = true;
- break;
- }
- }
- ++C;
- }
- if (attached)
- insert(qmlattachedproperties,*c,style,Okay);
- else
- insert(qmlproperties,*c,style,Okay);
+ if ((*c)->type() == Node::QmlPropertyGroup) {
+ insert(qmlproperties,*c,style,Okay);
}
else if ((*c)->type() == Node::QmlProperty) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
@@ -1278,8 +1237,8 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
}
NodeList::ConstIterator c = current->childNodes().constBegin();
while (c != current->childNodes().constEnd()) {
- if ((*c)->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
+ if ((*c)->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*c);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp
index 5c25eeedc4..3e63432047 100644
--- a/src/tools/qdoc/cppcodeparser.cpp
+++ b/src/tools/qdoc/cppcodeparser.cpp
@@ -272,37 +272,42 @@ void CppCodeParser::doneParsingSourceFiles()
qdb_->treeRoot()->makeUndocumentedChildrenInternal();
}
+static QSet<QString> topicCommands_;
/*!
Returns the set of strings reopresenting the topic commands.
*/
-QSet<QString> CppCodeParser::topicCommands()
+const QSet<QString>& CppCodeParser::topicCommands()
{
- return QSet<QString>() << COMMAND_CLASS
- << COMMAND_DITAMAP
- << COMMAND_ENUM
- << COMMAND_EXAMPLE
- << COMMAND_EXTERNALPAGE
- << COMMAND_FILE
- << COMMAND_FN
- << COMMAND_GROUP
- << COMMAND_HEADERFILE
- << COMMAND_MACRO
- << COMMAND_MODULE
- << COMMAND_NAMESPACE
- << COMMAND_PAGE
- << COMMAND_PROPERTY
- << COMMAND_TYPEDEF
- << COMMAND_VARIABLE
- << COMMAND_QMLCLASS
- << COMMAND_QMLTYPE
- << COMMAND_QMLPROPERTY
- << COMMAND_QMLATTACHEDPROPERTY
- << COMMAND_QMLSIGNAL
- << COMMAND_QMLATTACHEDSIGNAL
- << COMMAND_QMLMETHOD
- << COMMAND_QMLATTACHEDMETHOD
- << COMMAND_QMLBASICTYPE
- << COMMAND_QMLMODULE;
+ if (topicCommands_.isEmpty()) {
+ topicCommands_ << COMMAND_CLASS
+ << COMMAND_DITAMAP
+ << COMMAND_ENUM
+ << COMMAND_EXAMPLE
+ << COMMAND_EXTERNALPAGE
+ << COMMAND_FILE
+ << COMMAND_FN
+ << COMMAND_GROUP
+ << COMMAND_HEADERFILE
+ << COMMAND_MACRO
+ << COMMAND_MODULE
+ << COMMAND_NAMESPACE
+ << COMMAND_PAGE
+ << COMMAND_PROPERTY
+ << COMMAND_TYPEDEF
+ << COMMAND_VARIABLE
+ << COMMAND_QMLCLASS
+ << COMMAND_QMLTYPE
+ << COMMAND_QMLPROPERTY
+ << COMMAND_QMLPROPERTYGROUP
+ << COMMAND_QMLATTACHEDPROPERTY
+ << COMMAND_QMLSIGNAL
+ << COMMAND_QMLATTACHEDSIGNAL
+ << COMMAND_QMLMETHOD
+ << COMMAND_QMLATTACHEDMETHOD
+ << COMMAND_QMLBASICTYPE
+ << COMMAND_QMLMODULE;
+ }
+ return topicCommands_;
}
/*!
@@ -607,10 +612,10 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
(command == COMMAND_QMLATTACHEDSIGNAL) ||
(command == COMMAND_QMLATTACHEDMETHOD)) {
QString module;
- QString element;
+ QString qmlType;
QString type;
- if (splitQmlMethodArg(arg.first,type,module,element)) {
- QmlClassNode* qmlClass = qdb_->findQmlType(module,element);
+ if (splitQmlMethodArg(arg.first,type,module,qmlType)) {
+ QmlClassNode* qmlClass = qdb_->findQmlType(module,qmlType);
if (qmlClass) {
bool attached = false;
Node::Type nodeType = Node::QmlMethod;
@@ -643,28 +648,57 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
}
/*!
+ A QML property group argument has the form...
+
+ <QML-module>::<QML-type>::<name>
+
+ This function splits the argument into those parts.
+ A <QML-module> is the QML equivalent of a C++ namespace.
+ So this function splits \a arg on "::" and stores the
+ parts in \a module, \a qmlType, and \a name, and returns
+ true. If any part is not found, a qdoc warning is emitted
+ and false is returned.
+ */
+bool CppCodeParser::splitQmlPropertyGroupArg(const QString& arg,
+ QString& module,
+ QString& qmlType,
+ QString& name)
+{
+ QStringList colonSplit = arg.split("::");
+ if (colonSplit.size() == 3) {
+ module = colonSplit[0];
+ qmlType = colonSplit[1];
+ name = colonSplit[2];
+ return true;
+ }
+ QString msg = "Unrecognizable QML module/component qualifier for " + arg;
+ location().warning(tr(msg.toLatin1().data()));
+ return false;
+}
+
+/*!
A QML property argument has the form...
- <type> <element>::<name>
- <type> <QML-module>::<element>::<name>
+ <type> <QML-type>::<name>
+ <type> <QML-module>::<QML-type>::<name>
This function splits the argument into one of those
two forms. The three part form is the old form, which
was used before the creation of Qt Quick 2 and Qt
Components. A <QML-module> is the QML equivalent of a
C++ namespace. So this function splits \a arg on "::"
- and stores the parts in \a type, \a module, \a element,
+ and stores the parts in \a type, \a module, \a qmlType,
and \a name, and returns true. If any part other than
\a module is not found, a qdoc warning is emitted and
false is returned.
- \note The two elements \e{Component} and \e{QtObject} never
- have a module qualifier.
+ \note The two QML types \e{Component} and \e{QtObject}
+ never have a module qualifier.
*/
bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
QString& type,
QString& module,
- QString& element,
+ QString& qmlType,
QString& name)
{
QStringList blankSplit = arg.split(QLatin1Char(' '));
@@ -673,13 +707,13 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
QStringList colonSplit(blankSplit[1].split("::"));
if (colonSplit.size() == 3) {
module = colonSplit[0];
- element = colonSplit[1];
+ qmlType = colonSplit[1];
name = colonSplit[2];
return true;
}
if (colonSplit.size() == 2) {
module.clear();
- element = colonSplit[0];
+ qmlType = colonSplit[0];
name = colonSplit[1];
return true;
}
@@ -696,21 +730,21 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
/*!
A QML signal or method argument has the form...
- <type> <element>::<name>(<param>, <param>, ...)
- <type> <QML-module>::<element>::<name>(<param>, <param>, ...)
+ <type> <QML-type>::<name>(<param>, <param>, ...)
+ <type> <QML-module>::<QML-type>::<name>(<param>, <param>, ...)
This function splits the argument into one of those two
- forms, sets \a module, \a element, and \a name, and returns
+ forms, sets \a module, \a qmlType, and \a name, and returns
true. If the argument doesn't match either form, an error
message is emitted and false is returned.
- \note The two elements \e{Component} and \e{QtObject} never
+ \note The two QML types \e{Component} and \e{QtObject} never
have a module qualifier.
*/
bool CppCodeParser::splitQmlMethodArg(const QString& arg,
QString& type,
QString& module,
- QString& element)
+ QString& qmlType)
{
QStringList colonSplit(arg.split("::"));
if (colonSplit.size() > 1) {
@@ -719,22 +753,22 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
type = blankSplit[0];
if (colonSplit.size() > 2) {
module = blankSplit[1];
- element = colonSplit[1];
+ qmlType = colonSplit[1];
}
else {
module.clear();
- element = blankSplit[1];
+ qmlType = blankSplit[1];
}
}
else {
type.clear();
if (colonSplit.size() > 2) {
module = colonSplit[0];
- element = colonSplit[1];
+ qmlType = colonSplit[1];
}
else {
module.clear();
- element = colonSplit[0];
+ qmlType = colonSplit[0];
}
}
return true;
@@ -750,79 +784,118 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
Currently, this function is called only for \e{qmlproperty}
and \e{qmlattachedproperty}.
*/
-Node* CppCodeParser::processTopicCommandGroup(const Doc& doc,
- const QString& command,
- const ArgList& args)
+void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs)
{
- QmlPropGroupNode* qmlPropGroup = 0;
- if ((command == COMMAND_QMLPROPERTY) ||
- (command == COMMAND_QMLATTACHEDPROPERTY)) {
- QString arg;
- QString type;
- QString module;
- QString element;
- QString property;
- QmlClassNode* qmlClass = 0;
- bool attached = (command == COMMAND_QMLATTACHEDPROPERTY);
- ArgList::ConstIterator argsIter = args.constBegin();
- arg = argsIter->first;
- if (splitQmlPropertyArg(arg,type,module,element,property)) {
- qmlClass = qdb_->findQmlType(module,element);
- if (qmlClass) {
- qmlPropGroup = new QmlPropGroupNode(qmlClass,property); //,attached);
- qmlPropGroup->setLocation(doc.startLocation());
- }
+ QString arg;
+ QString type;
+ QString topic;
+ QString module;
+ QString qmlType;
+ QString property;
+ QmlPropertyNode* qpn = 0;
+ QmlClassNode* qmlClass = 0;
+ QmlPropertyGroupNode* qpgn = 0;
+
+ Topic qmlPropertyGroupTopic;
+ const TopicList& topics = doc.topicsUsed();
+ for (int i=0; i<topics.size(); ++i) {
+ if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP) {
+ qmlPropertyGroupTopic = topics.at(i);
+ break;
}
- if (qmlPropGroup) {
- if (qmlClass->hasProperty(property)) {
- doc.startLocation().warning(tr("QML property documented multiple times: '%1'").arg(arg));
+ }
+ if (qmlPropertyGroupTopic.isEmpty() && topics.size() > 1) {
+ qmlPropertyGroupTopic = topics.at(0);
+ qmlPropertyGroupTopic.topic = COMMAND_QMLPROPERTYGROUP;
+ arg = qmlPropertyGroupTopic.args;
+ if (splitQmlPropertyArg(arg, type, module, qmlType, property)) {
+ int i = property.indexOf('.');
+ if (i != -1) {
+ property = property.left(i);
+ qmlPropertyGroupTopic.args = module + "::" + qmlType + "::" + property;
+ doc.location().warning(tr("No QML property group command found; using \\%1 %2")
+ .arg(COMMAND_QMLPROPERTYGROUP).arg(qmlPropertyGroupTopic.args));
}
else {
- QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlPropGroup,property,type,attached);
- qmlPropNode->setLocation(doc.startLocation());
+ /*
+ Assumption: No '.' in the property name
+ means there is no property group.
+ */
+ qmlPropertyGroupTopic.clear();
+ }
+ }
+ }
+
+ if (!qmlPropertyGroupTopic.isEmpty()) {
+ arg = qmlPropertyGroupTopic.args;
+ if (splitQmlPropertyGroupArg(arg, module, qmlType, property)) {
+ qmlClass = qdb_->findQmlType(module, qmlType);
+ if (qmlClass) {
+ qpgn = new QmlPropertyGroupNode(qmlClass, property);
+ qpgn->setLocation(doc.startLocation());
}
- ++argsIter;
- while (argsIter != args.constEnd()) {
- arg = argsIter->first;
- if (splitQmlPropertyArg(arg,type,module,element,property)) {
- if (qmlClass->hasProperty(property)) {
- doc.startLocation().warning(tr("QML property documented multiple times: '%1'").arg(arg));
+ }
+ if (topics.size() == 1) {
+ nodes.append(qpgn);
+ docs.append(doc);
+ return;
+ }
+ }
+ for (int i=0; i<topics.size(); ++i) {
+ if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP)
+ continue;
+ topic = topics.at(i).topic;
+ arg = topics.at(i).args;
+ if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ bool attached = (topic == COMMAND_QMLATTACHEDPROPERTY);
+ if (splitQmlPropertyArg(arg, type, module, qmlType, property)) {
+ qmlClass = qdb_->findQmlType(module, qmlType);
+ if (qmlClass) {
+ if (qmlClass->hasQmlProperty(property) != 0) {
+ QString msg = tr("QML property documented multiple times: '%1'").arg(arg);
+ doc.startLocation().warning(msg);
+ }
+ else if (qpgn) {
+ qpn = new QmlPropertyNode(qpgn, property, type, attached);
+ qpn->setLocation(doc.startLocation());
}
else {
- QmlPropertyNode* qmlPropNode = new QmlPropertyNode(qmlPropGroup,
- property,
- type,
- attached);
- qmlPropNode->setLocation(doc.startLocation());
+ qpn = new QmlPropertyNode(qmlClass, property, type, attached);
+ qpn->setLocation(doc.startLocation());
+ nodes.append(qpn);
+ docs.append(doc);
}
}
- ++argsIter;
}
}
}
- return qmlPropGroup;
}
+static QSet<QString> otherMetaCommands_;
/*!
Returns the set of strings representing the common metacommands
plus some other metacommands.
*/
-QSet<QString> CppCodeParser::otherMetaCommands()
+const QSet<QString>& CppCodeParser::otherMetaCommands()
{
- return commonMetaCommands() << COMMAND_INHEADERFILE
- << COMMAND_OVERLOAD
- << COMMAND_REIMP
- << COMMAND_RELATES
- << COMMAND_CONTENTSPAGE
- << COMMAND_NEXTPAGE
- << COMMAND_PREVIOUSPAGE
- << COMMAND_INDEXPAGE
- << COMMAND_STARTPAGE
- << COMMAND_QMLINHERITS
- << COMMAND_QMLINSTANTIATES
- << COMMAND_QMLDEFAULT
- << COMMAND_QMLREADONLY
- << COMMAND_QMLABSTRACT;
+ if (otherMetaCommands_.isEmpty()) {
+ otherMetaCommands_ = commonMetaCommands();
+ otherMetaCommands_ << COMMAND_INHEADERFILE
+ << COMMAND_OVERLOAD
+ << COMMAND_REIMP
+ << COMMAND_RELATES
+ << COMMAND_CONTENTSPAGE
+ << COMMAND_NEXTPAGE
+ << COMMAND_PREVIOUSPAGE
+ << COMMAND_INDEXPAGE
+ << COMMAND_STARTPAGE
+ << COMMAND_QMLINHERITS
+ << COMMAND_QMLINSTANTIATES
+ << COMMAND_QMLDEFAULT
+ << COMMAND_QMLREADONLY
+ << COMMAND_QMLABSTRACT;
+ }
+ return otherMetaCommands_;
}
/*!
@@ -855,8 +928,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
}
}
else if (command == COMMAND_REIMP) {
- if (node->parent() && !node->parent()->isInternal()) {
- if (node != 0 && node->type() == Node::Function) {
+ if (node != 0 && node->parent() && !node->parent()->isInternal()) {
+ if (node->type() == Node::Function) {
FunctionNode *func = (FunctionNode *) node;
const FunctionNode *from = func->reimplementedFrom();
if (from == 0) {
@@ -961,8 +1034,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setDefault();
}
- else if (node->type() == Node::Document && node->subType() == Node::QmlPropertyGroup) {
- QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
+ else if (node->type() == Node::QmlPropertyGroup) {
+ QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
@@ -978,8 +1051,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setReadOnly(1);
}
- else if (node->type() == Node::Document && node->subType() == Node::QmlPropertyGroup) {
- QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
+ else if (node->type() == Node::QmlPropertyGroup) {
+ QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
@@ -2067,10 +2140,9 @@ bool CppCodeParser::matchDeclList(InnerNode *parent)
bool CppCodeParser::matchDocsAndStuff()
{
ExtraFuncData extra;
- QSet<QString> topicCommandsAllowed = topicCommands();
- QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
- QSet<QString> metacommandsAllowed = topicCommandsAllowed +
- otherMetacommandsAllowed;
+ const QSet<QString>& topicCommandsAllowed = topicCommands();
+ const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
+ const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
while (tok != Tok_Eoi) {
if (tok == Tok_Doc) {
@@ -2087,25 +2159,22 @@ bool CppCodeParser::matchDocsAndStuff()
/*
Doc parses the comment.
*/
- Doc doc(start_loc,end_loc,comment,metacommandsAllowed);
-
+ Doc doc(start_loc,end_loc,comment,metacommandsAllowed, topicCommandsAllowed);
QString topic;
- ArgList args;
-
- QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
+ bool isQmlPropertyTopic = false;
- /*
- There should be one topic command in the set,
- or none. If the set is empty, then the comment
- should be a function description.
- */
- if (topicCommandsUsed.count() > 0) {
- topic = *topicCommandsUsed.constBegin();
- args = doc.metaCommandArgs(topic);
+ const TopicList& topics = doc.topicsUsed();
+ if (!topics.isEmpty()) {
+ topic = topics[0].topic;
+ if ((topic == COMMAND_QMLPROPERTY) ||
+ (topic == COMMAND_QMLPROPERTYGROUP) ||
+ (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ isQmlPropertyTopic = true;
+ }
}
-
+ // if (isQmlPropertyTopic && doc.location().fileName().endsWith("qquickitem.cpp")) {
NodeList nodes;
- QList<Doc> docs;
+ DocList docs;
if (topic.isEmpty()) {
QStringList parentPath;
@@ -2133,43 +2202,39 @@ bool CppCodeParser::matchDocsAndStuff()
.arg(COMMAND_FN).arg(COMMAND_PAGE));
}
}
+ else if (isQmlPropertyTopic) {
+ Doc nodeDoc = doc;
+ processQmlProperties(nodeDoc, nodes, docs);
+ }
else {
- /*
- There is a topic command. Process it.
- */
- if ((topic == COMMAND_QMLPROPERTY) ||
- (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ ArgList args;
+ const QSet<QString>& topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
+ if (topicCommandsUsed.count() > 0) {
+ topic = *topicCommandsUsed.constBegin();
+ args = doc.metaCommandArgs(topic);
+ }
+ if (topicCommandsUsed.count() > 1) {
+ QString topics;
+ QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
+ while (t != topicCommandsUsed.constEnd()) {
+ topics += " \\" + *t + ",";
+ ++t;
+ }
+ topics[topics.lastIndexOf(',')] = '.';
+ int i = topics.lastIndexOf(',');
+ topics[i] = ' ';
+ topics.insert(i+1,"and");
+ doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
+ }
+ ArgList::ConstIterator a = args.constBegin();
+ while (a != args.constEnd()) {
Doc nodeDoc = doc;
- Node *node = processTopicCommandGroup(nodeDoc, topic,args);
+ Node *node = processTopicCommand(nodeDoc,topic,*a);
if (node != 0) {
nodes.append(node);
docs.append(nodeDoc);
}
- }
- else {
- if (topicCommandsUsed.count() > 1) {
- QString topics;
- QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
- while (t != topicCommandsUsed.constEnd()) {
- topics += " \\" + *t + ",";
- ++t;
- }
- topics[topics.lastIndexOf(',')] = '.';
- int i = topics.lastIndexOf(',');
- topics[i] = ' ';
- topics.insert(i+1,"and");
- doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
- }
- ArgList::ConstIterator a = args.constBegin();
- while (a != args.constEnd()) {
- Doc nodeDoc = doc;
- Node *node = processTopicCommand(nodeDoc,topic,*a);
- if (node != 0) {
- nodes.append(node);
- docs.append(nodeDoc);
- }
- ++a;
- }
+ ++a;
}
}
@@ -2262,7 +2327,7 @@ bool CppCodeParser::makeFunctionNode(const QString& signature,
the \a type.
\a parent is the QML class node. The QML module and QML
- element names have already been consumed to find \a parent.
+ type names have already been consumed to find \a parent.
What remains in \a sig is the method signature. The method
must be a child of \a parent.
*/
diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h
index 957142712b..5ab72f7f54 100644
--- a/src/tools/qdoc/cppcodeparser.h
+++ b/src/tools/qdoc/cppcodeparser.h
@@ -84,13 +84,16 @@ public:
virtual void doneParsingSourceFiles();
protected:
- virtual QSet<QString> topicCommands();
+ const QSet<QString>& topicCommands();
+ const QSet<QString>& otherMetaCommands();
virtual Node* processTopicCommand(const Doc& doc,
const QString& command,
const ArgLocPair& arg);
- virtual Node *processTopicCommandGroup(const Doc& doc,
- const QString& command,
- const ArgList& args);
+ void processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs);
+ bool splitQmlPropertyGroupArg(const QString& arg,
+ QString& module,
+ QString& element,
+ QString& name);
bool splitQmlPropertyArg(const QString& arg,
QString& type,
QString& module,
@@ -100,7 +103,6 @@ protected:
QString& type,
QString& module,
QString& element);
- virtual QSet<QString> otherMetaCommands();
virtual void processOtherMetaCommand(const Doc& doc,
const QString& command,
const ArgLocPair& argLocPair,
@@ -212,6 +214,7 @@ protected:
#define COMMAND_QMLCLASS Doc::alias("qmlclass")
#define COMMAND_QMLTYPE Doc::alias("qmltype")
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
+#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
#define COMMAND_QMLINHERITS Doc::alias("inherits")
#define COMMAND_QMLINSTANTIATES Doc::alias("instantiates")
@@ -238,6 +241,7 @@ protected:
#define COMMAND_LICENSENAME Doc::alias("licensename")
#define COMMAND_LICENSEDESCRIPTION Doc::alias("licensedescription")
#define COMMAND_RELEASEDATE Doc::alias("releasedate")
+#define COMMAND_QTVARIABLE Doc::alias("qtvariable")
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index 96f5519be4..46fb6e27e6 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -3677,8 +3677,8 @@ QString DitaXmlGenerator::guidForNode(const Node* node)
return fn->guid();
}
case Node::Document:
- if (node->subType() != Node::QmlPropertyGroup)
- break;
+ break;
+ case Node::QmlPropertyGroup:
case Node::QmlProperty:
case Node::Property:
return node->guid();
@@ -3698,7 +3698,7 @@ QString DitaXmlGenerator::guidForNode(const Node* node)
Constructs a file name appropriate for the \a node and returns
it. If the \a node is not a fake node, or if it is a fake node but
it is neither an external page node nor an image node or a ditamap,
- call the PageGenerator::fileName() function.
+ call the Generator::fileName() function.
*/
QString DitaXmlGenerator::fileName(const Node* node)
{
@@ -3743,7 +3743,7 @@ QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
}
QString link = fn;
- if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
+ if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
QString guid = guidForNode(node);
if (relative && fn == fileName(relative) && guid == guidForNode(relative)) {
return QString();
@@ -3758,7 +3758,7 @@ QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
back down into the other subdirectory.
*/
if (node && relative && (node != relative)) {
- if (node->outputSubdirectory() != relative->outputSubdirectory())
+ if (useOutputSubdirs() && node->outputSubdirectory() != relative->outputSubdirectory())
link.prepend(QString("../" + node->outputSubdirectory() + QLatin1Char('/')));
}
return link;
@@ -4079,8 +4079,8 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node,
QString marked;
QmlPropertyNode* qpn = 0;
- if (node->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ if (node->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
if (qpgn->childNodes().size() == 1) {
qpn = static_cast<QmlPropertyNode*>(*p);
@@ -4114,50 +4114,10 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node,
}
else if (node->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(node);
- if (qpn->qmlPropNodes().isEmpty()) {
- startQmlProperty(qpn,relative,marker);
- writeApiDesc(node, marker, node->title());
- writeEndTag(); // </qmlPropertyDetail>
- writeEndTag(); // </qmlProperty>
- }
- else if (qpn->qmlPropNodes().size() == 1) {
- Node* n = qpn->qmlPropNodes().at(0);
- if (n->type() == Node::QmlProperty) {
- qpn = static_cast<QmlPropertyNode*>(n);
- startQmlProperty(qpn,relative,marker);
- writeApiDesc(node, marker, node->title());
- writeEndTag(); // </qmlPropertyDetail>
- writeEndTag(); // </qmlProperty>
- }
- }
- else {
- /*
- The QML property node has multiple override nodes.
- Process the whole list as we would for a QML property
- group.
- */
- writeStartTag(DT_qmlPropertyGroup);
- QString id = "id-qml-propertygroup-" + node->name();
- id.replace('.','-');
- xmlWriter().writeAttribute("id",id);
- writeStartTag(DT_apiName);
- //writeCharacters("...");
- writeEndTag(); // </apiName>
- writeStartTag(DT_qmlPropertyGroupDetail);
- writeApiDesc(node, marker, node->title());
- writeEndTag(); // </qmlPropertyGroupDetail>
- NodeList::ConstIterator p = qpn->qmlPropNodes().constBegin();
- while (p != qpn->qmlPropNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p);
- startQmlProperty(q,relative,marker);
- writeEndTag(); // </qmlPropertyDetail>
- writeEndTag(); // </qmlProperty>
- }
- ++p;
- }
- writeEndTag(); // </qmlPropertyGroup
- }
+ startQmlProperty(qpn,relative,marker);
+ writeApiDesc(node, marker, node->title());
+ writeEndTag(); // </qmlPropertyDetail>
+ writeEndTag(); // </qmlProperty>
}
else if (node->type() == Node::QmlSignal)
writeQmlRef(DT_qmlSignal,node,relative,marker);
@@ -5326,13 +5286,13 @@ DitaXmlGenerator::generateInnerNode(InnerNode* node)
return;
if (docNode->subType() == Node::Image)
return;
- if (docNode->subType() == Node::QmlPropertyGroup)
- return;
if (docNode->subType() == Node::Page) {
if (node->count() > 0)
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
}
}
+ else if (node->type() == Node::QmlPropertyGroup)
+ return;
/*
Obtain a code marker for the source file.
@@ -5487,8 +5447,6 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
if (!isDuplicate(nodeSubtypeMaps[Node::QmlClass],child->title(),child))
nodeSubtypeMaps[Node::QmlClass]->insert(child->title(),child);
break;
- case Node::QmlPropertyGroup:
- break;
case Node::QmlBasicType:
if (!isDuplicate(nodeSubtypeMaps[Node::QmlBasicType],child->title(),child))
nodeSubtypeMaps[Node::QmlBasicType]->insert(child->title(),child);
@@ -5517,6 +5475,8 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
break;
case Node::QmlProperty:
break;
+ case Node::QmlPropertyGroup:
+ break;
case Node::QmlSignal:
break;
case Node::QmlSignalHandler:
diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp
index 42b98502e0..1e0c66cd08 100644
--- a/src/tools/qdoc/doc.cpp
+++ b/src/tools/qdoc/doc.cpp
@@ -80,7 +80,6 @@ enum {
CMD_ANNOTATEDLIST,
CMD_B,
CMD_BADCODE,
- CMD_BASENAME,
CMD_BOLD,
CMD_BR,
CMD_BRIEF,
@@ -126,6 +125,7 @@ enum {
CMD_INCLUDE,
CMD_INLINEIMAGE,
CMD_INDEX,
+ CMD_INPUT,
CMD_KEYWORD,
CMD_L,
CMD_LEGALESE,
@@ -198,7 +198,6 @@ static struct {
{ "annotatedlist", CMD_ANNOTATEDLIST, 0 },
{ "b", CMD_B, 0 },
{ "badcode", CMD_BADCODE, 0 },
- { "basename", CMD_BASENAME, 0 }, // ### don't document for now
{ "bold", CMD_BOLD, 0 },
{ "br", CMD_BR, 0 },
{ "brief", CMD_BRIEF, 0 },
@@ -244,6 +243,7 @@ static struct {
{ "include", CMD_INCLUDE, 0 },
{ "inlineimage", CMD_INLINEIMAGE, 0 },
{ "index", CMD_INDEX, 0 }, // ### don't document for now
+ { "input", CMD_INPUT, 0 },
{ "keyword", CMD_KEYWORD, 0 },
{ "l", CMD_L, 0 },
{ "legalese", CMD_LEGALESE, 0 },
@@ -316,7 +316,6 @@ Q_GLOBAL_STATIC(QHash_QString_Macro, macroHash)
class DocPrivateExtra
{
public:
- QString baseName;
Doc::Sections granularity;
Doc::Sections section; // ###
QList<Atom*> tableOfContents;
@@ -376,7 +375,7 @@ public:
bool hasLegalese : 1;
bool hasSectioningUnits : 1;
DocPrivateExtra *extra;
- TopicList topics;
+ TopicList topics_;
DitaRefList ditamap_;
};
@@ -466,7 +465,6 @@ private:
Location& location();
QString detailsUnknownCommand(const QSet<QString>& metaCommandSet,
const QString& str);
- void insertBaseName(const QString &baseName);
void insertTarget(const QString& target, bool keyword);
void include(const QString& fileName, const QString& identifier);
void startFormat(const QString& format, int cmd);
@@ -571,7 +569,7 @@ void DocParser::parse(const QString& source,
cachedPos = 0;
priv = docPrivate;
priv->text << Atom::Nop;
- priv->topics.clear();
+ priv->topics_.clear();
paraState = OutsideParagraph;
inTableHeader = false;
@@ -644,10 +642,6 @@ void DocParser::parse(const QString& source,
leavePara();
append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
break;
- case CMD_BASENAME:
- leavePara();
- insertBaseName(getArgument());
- break;
case CMD_BR:
leavePara();
append(Atom::BR);
@@ -931,6 +925,7 @@ void DocParser::parse(const QString& source,
enterPara(Atom::ImportantLeft, Atom::ImportantRight);
break;
case CMD_INCLUDE:
+ case CMD_INPUT:
{
QString fileName = getArgument();
QString identifier = getRestOfLine();
@@ -1404,7 +1399,7 @@ void DocParser::parse(const QString& source,
QString arg = getMetaCommandArgument(cmdStr);
priv->metaCommandMap[cmdStr].append(ArgLocPair(arg,location()));
if (possibleTopics.contains(cmdStr)) {
- priv->topics.append(Topic(cmdStr,arg));
+ priv->topics_.append(Topic(cmdStr,arg));
}
}
else if (macroHash()->contains(cmdStr)) {
@@ -1669,29 +1664,6 @@ QString DocParser::detailsUnknownCommand(const QSet<QString> &metaCommandSet,
return tr("Maybe you meant '\\%1'?").arg(best);
}
-void DocParser::insertBaseName(const QString &baseName)
-{
- priv->constructExtra();
- if (currentSection == priv->extra->section) {
- priv->extra->baseName = baseName;
- }
- else {
- Atom *atom = priv->text.firstAtom();
- Atom *sectionLeft = 0;
-
- int delta = currentSection - priv->extra->section;
-
- while (atom != 0) {
- if (atom->type() == Atom::SectionLeft &&
- atom->string().toInt() == delta)
- sectionLeft = atom;
- atom = atom->next();
- }
- if (sectionLeft != 0)
- (void) new Atom(sectionLeft, Atom::BaseName, baseName);
- }
-}
-
void DocParser::insertTarget(const QString &target, bool keyword)
{
if (targetMap.contains(target)) {
@@ -1712,16 +1684,17 @@ void DocParser::insertTarget(const QString &target, bool keyword)
void DocParser::include(const QString& fileName, const QString& identifier)
{
if (location().depth() > 16)
- location().fatal(tr("Too many nested '\\%1's")
- .arg(cmdName(CMD_INCLUDE)));
+ location().fatal(tr("Too many nested '\\%1's").arg(cmdName(CMD_INCLUDE)));
QString userFriendlyFilePath;
- // ### use current directory?
+ QString filePath = Doc::config()->getIncludeFilePath(fileName);
+#if 0
QString filePath = Config::findFile(location(),
sourceFiles,
sourceDirs,
fileName,
userFriendlyFilePath);
+#endif
if (filePath.isEmpty()) {
location().warning(tr("Cannot find qdoc include file '%1'").arg(fileName));
}
@@ -2751,6 +2724,7 @@ QString DocParser::slashed(const QString& str)
#define COMMAND_BRIEF Doc::alias("brief")
#define COMMAND_QMLBRIEF Doc::alias("qmlbrief")
+#if 0
Doc::Doc(const Location& start_loc,
const Location& end_loc,
const QString& source,
@@ -2760,6 +2734,7 @@ Doc::Doc(const Location& start_loc,
DocParser parser;
parser.parse(source,priv,metaCommandSet,QSet<QString>());
}
+#endif
/*!
Parse the qdoc comment \a source. Build up a list of all the topic
@@ -2978,17 +2953,6 @@ Text Doc::legaleseText() const
return body().subText(Atom::LegaleseLeft, Atom::LegaleseRight);
}
-const QString& Doc::baseName() const
-{
- static QString null;
- if (priv == 0 || priv->extra == 0) {
- return null;
- }
- else {
- return priv->extra->baseName;
- }
-}
-
Doc::Sections Doc::granularity() const
{
if (priv == 0 || priv->extra == 0) {
@@ -3026,7 +2990,7 @@ const QSet<QString> &Doc::metaCommandsUsed() const
*/
const TopicList& Doc::topicsUsed() const
{
- return priv == 0 ? *nullTopicList() : priv->topics;
+ return priv == 0 ? *nullTopicList() : priv->topics_;
}
ArgList Doc::metaCommandArgs(const QString& metacommand) const
@@ -3083,6 +3047,8 @@ const QStringMultiMap &Doc::metaTagMap() const
return priv && priv->extra ? priv->extra->metaMap : *null_QStringMultiMap();
}
+const Config* Doc::config_ = 0;
+
void Doc::initialize(const Config& config)
{
DocParser::tabSize = config.getInt(CONFIG_TABSIZE);
@@ -3093,8 +3059,8 @@ void Doc::initialize(const Config& config)
DocParser::quoting = config.getBool(CONFIG_QUOTINGINFORMATION);
QmlClassNode::qmlOnly = config.getBool(CONFIG_QMLONLY);
-
QStringMap reverseAliasMap;
+ config_ = &config;
QSet<QString> commands = config.subVars(CONFIG_ALIAS);
QSet<QString>::ConstIterator c = commands.constBegin();
diff --git a/src/tools/qdoc/doc.h b/src/tools/qdoc/doc.h
index ca9787595f..65007634a6 100644
--- a/src/tools/qdoc/doc.h
+++ b/src/tools/qdoc/doc.h
@@ -71,7 +71,10 @@ struct Topic
{
QString topic;
QString args;
+ Topic() { }
Topic(QString& t, QString a) : topic(t), args(a) { }
+ bool isEmpty() const { return topic.isEmpty(); }
+ void clear() { topic.clear(); args.clear(); }
};
typedef QList<Topic> TopicList;
@@ -136,10 +139,6 @@ public:
};
Doc() : priv(0) {}
- Doc(const Location &start_loc,
- const Location &end_loc,
- const QString &source,
- const QSet<QString> &metaCommandSet);
Doc(const Location& start_loc,
const Location& end_loc,
const QString& source,
@@ -165,7 +164,6 @@ public:
Text briefText(bool inclusive = false) const;
Text trimmedBriefText(const QString &className) const;
Text legaleseText() const;
- const QString& baseName() const;
Sections granularity() const;
const QSet<QString> &parameterNames() const;
const QStringList &enumItemNames() const;
@@ -191,11 +189,14 @@ public:
Quoter &quoter,
const QString &fileName);
static QString canonicalTitle(const QString &title);
+ static const Config* config() { return config_; }
private:
void detach();
DocPrivate *priv;
+ static const Config* config_;
};
+typedef QList<Doc> DocList;
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/doc/config/qdoc.qdocconf b/src/tools/qdoc/doc/config/qdoc.qdocconf
index a7fbb38463..a6ae18a675 100644
--- a/src/tools/qdoc/doc/config/qdoc.qdocconf
+++ b/src/tools/qdoc/doc/config/qdoc.qdocconf
@@ -70,3 +70,5 @@ depends += \
qtwebkitexamples \
qtxml \
qtxmlpatterns
+
+navigation.landingpage = "QDoc Manual"
diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp
index 889f0f55ca..5583600bf6 100644
--- a/src/tools/qdoc/generator.cpp
+++ b/src/tools/qdoc/generator.cpp
@@ -97,7 +97,9 @@ QStringList Generator::styleDirs;
QStringList Generator::styleFiles;
bool Generator::debugging_ = false;
bool Generator::noLinkErrors_ = false;
+bool Generator::redirectDocumentationToDevNull_ = false;
Generator::Passes Generator::qdocPass_ = Both;
+bool Generator::useOutputSubdirs_ = true;
void Generator::setDebugSegfaultFlag(bool b)
{
@@ -263,14 +265,17 @@ void Generator::writeOutFileNames()
void Generator::beginSubPage(const InnerNode* node, const QString& fileName)
{
QString path = outputDir() + QLatin1Char('/');
- if (!node->outputSubdirectory().isEmpty())
+ if (Generator::useOutputSubdirs() && !node->outputSubdirectory().isEmpty())
path += node->outputSubdirectory() + QLatin1Char('/');
path += fileName;
- Generator::debugSegfault("Writing: " + path);
- outFileNames.insert(fileName,fileName);
- QFile* outFile = new QFile(path);
+
+ QFile* outFile = new QFile(redirectDocumentationToDevNull_ ? QStringLiteral("/dev/null") : path);
+ if (outFile->exists())
+ node->location().error(tr("HTML file already exists; overwriting %1").arg(outFile->fileName()));
if (!outFile->open(QFile::WriteOnly))
node->location().fatal(tr("Cannot open output file '%1'").arg(outFile->fileName()));
+ Generator::debugSegfault("Writing: " + path);
+ outFileNames.insert(fileName,fileName);
QTextStream* out = new QTextStream(outFile);
#ifndef QT_NO_TEXTCODEC
@@ -299,14 +304,22 @@ QString Generator::fileBase(const Node *node) const
node = node->relates();
else if (!node->isInnerNode())
node = node->parent();
- if (node->subType() == Node::QmlPropertyGroup) {
+ if (node->type() == Node::QmlPropertyGroup) {
node = node->parent();
}
- QString base = node->doc().baseName();
- if (!base.isEmpty())
- return base;
+ if (node->type() == Node::Document && node->subType() == Node::Collision) {
+ const NameCollisionNode* ncn = static_cast<const NameCollisionNode*>(node);
+ if (ncn->currentChild())
+ return fileBase(ncn->currentChild());
+ }
+
+ if (node->hasBaseName()) {
+ //qDebug() << "RETURNING:" << node->baseName();
+ return node->baseName();
+ }
+ QString base;
const Node *p = node;
forever {
@@ -345,6 +358,11 @@ QString Generator::fileBase(const Node *node) const
if (node->subType() == Node::Module) {
base.append("-module");
}
+ if (node->isExample() || node->isExampleFile())
+ base.prepend(project.toLower() + QLatin1Char('-'));
+ if (node->isExample())
+ base.append(QLatin1String("-example"));
+
}
// the code below is effectively equivalent to:
@@ -375,6 +393,8 @@ QString Generator::fileBase(const Node *node) const
}
while (res.endsWith(QLatin1Char('-')))
res.chop(1);
+ Node* n = const_cast<Node*>(node);
+ n->setBaseName(res);
return res;
}
@@ -407,7 +427,7 @@ QMap<QString, QString>& Generator::formattingRightMap()
/*!
Returns the full document location.
*/
-QString Generator::fullDocumentLocation(const Node *node, bool subdir)
+QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
{
if (!node)
return QString();
@@ -419,11 +439,11 @@ QString Generator::fullDocumentLocation(const Node *node, bool subdir)
QString fdl;
/*
- If the output is being sent to subdirectories of the
- output directory, and if the subdir parameter is set,
- prepend the subdirectory name + '/' to the result.
+ If the useSubdir parameter is set, then the output is
+ being sent to subdirectories of the output directory.
+ Prepend the subdirectory name + '/' to the result.
*/
- if (subdir) {
+ if (useSubdir) {
fdl = node->outputSubdirectory();
if (!fdl.isEmpty())
fdl.append(QLatin1Char('/'));
@@ -467,7 +487,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool subdir)
parentName = fullDocumentLocation(node->relates());
}
else if ((parentNode = node->parent())) {
- if (parentNode->subType() == Node::QmlPropertyGroup) {
+ if (parentNode->type() == Node::QmlPropertyGroup) {
parentNode = parentNode->parent();
parentName = fullDocumentLocation(parentNode);
}
@@ -933,6 +953,8 @@ void Generator::generateInnerNode(InnerNode* node)
{
if (!node->url().isNull())
return;
+ if (node->isIndexNode())
+ return;
if (node->type() == Node::Document) {
DocNode* docNode = static_cast<DocNode*>(node);
@@ -940,13 +962,13 @@ void Generator::generateInnerNode(InnerNode* node)
return;
if (docNode->subType() == Node::Image)
return;
- if (docNode->subType() == Node::QmlPropertyGroup)
- return;
if (docNode->subType() == Node::Page) {
if (node->count() > 0)
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
}
}
+ else if (node->type() == Node::QmlPropertyGroup)
+ return;
/*
Obtain a code marker for the source file.
@@ -1099,7 +1121,10 @@ void Generator::generateSince(const Node *node, CodeMarker *marker)
if (project.isEmpty())
text << "version";
else
- text << project;
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
text << " " << since[0];
} else {
// Reconstruct the <project> <version> string.
@@ -1474,7 +1499,12 @@ QString Generator::indent(int level, const QString& markedCode)
void Generator::initialize(const Config &config)
{
+
+ if (config.getBool(QString("HTML.nosubdirs")))
+ resetUseOutputSubdirs();
+
outputFormats = config.getOutputFormats();
+ redirectDocumentationToDevNull_ = config.getBool(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL);
if (!outputFormats.isEmpty()) {
outDir_ = config.getOutputDir();
if (outDir_.isEmpty()) {
@@ -1487,7 +1517,7 @@ void Generator::initialize(const Config &config)
QDir dirInfo;
if (dirInfo.exists(outDir_)) {
- if (!runGenerateOnly()) {
+ if (!runGenerateOnly() && Generator::useOutputSubdirs()) {
if (!Config::removeDirContents(outDir_))
config.lastLocation().error(tr("Cannot empty output directory '%1'").arg(outDir_));
}
@@ -1907,8 +1937,6 @@ QString Generator::typeString(const Node *node)
switch (node->subType()) {
case Node::QmlClass:
return "type";
- case Node::QmlPropertyGroup:
- return "property group";
case Node::QmlBasicType:
return "type";
default:
@@ -1923,6 +1951,16 @@ QString Generator::typeString(const Node *node)
return "function";
case Node::Property:
return "property";
+ case Node::QmlPropertyGroup:
+ return "property group";
+ case Node::QmlProperty:
+ return "QML property";
+ case Node::QmlSignal:
+ return "QML signal";
+ case Node::QmlSignalHandler:
+ return "QML signal handler";
+ case Node::QmlMethod:
+ return "QML method";
default:
return "documentation";
}
diff --git a/src/tools/qdoc/generator.h b/src/tools/qdoc/generator.h
index 58e9073922..52d73e8dea 100644
--- a/src/tools/qdoc/generator.h
+++ b/src/tools/qdoc/generator.h
@@ -81,7 +81,7 @@ public:
virtual void initializeGenerator(const Config &config);
virtual void terminateGenerator();
- QString fullDocumentLocation(const Node *node, bool subdir = false);
+ QString fullDocumentLocation(const Node *node, bool useSubdir = false);
const Config* config() { return config_; }
static Generator *currentGenerator() { return currentGenerator_; }
@@ -100,6 +100,8 @@ public:
static bool runPrepareOnly() { return (qdocPass_ == Prepare); }
static bool runGenerateOnly() { return (qdocPass_ == Generate); }
static QString defaultModuleName() { return project; }
+ static void resetUseOutputSubdirs() { useOutputSubdirs_ = false; }
+ static bool useOutputSubdirs() { return useOutputSubdirs_; }
protected:
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
@@ -185,6 +187,17 @@ protected:
QString tagFile_;
QStack<QTextStream*> outStreamStack;
+ void appendFullName(Text& text,
+ const Node *apparentNode,
+ const Node *relative,
+ const Node *actualNode = 0);
+ void appendFullName(Text& text,
+ const Node *apparentNode,
+ const QString& fullName,
+ const Node *actualNode);
+ void appendFullNames(Text& text, const NodeList& nodes, const Node* relative);
+ void appendSortedNames(Text& text, const ClassNode *classe, const QList<RelatedClass> &classes);
+
private:
static Generator* currentGenerator_;
static QStringList exampleDirs;
@@ -206,18 +219,10 @@ private:
static QStringList styleFiles;
static bool debugging_;
static bool noLinkErrors_;
+ static bool redirectDocumentationToDevNull_;
static Passes qdocPass_;
+ static bool useOutputSubdirs_;
- void appendFullName(Text& text,
- const Node *apparentNode,
- const Node *relative,
- const Node *actualNode = 0);
- void appendFullName(Text& text,
- const Node *apparentNode,
- const QString& fullName,
- const Node *actualNode);
- void appendFullNames(Text& text, const NodeList& nodes, const Node* relative);
- void appendSortedNames(Text& text, const ClassNode *classe, const QList<RelatedClass> &classes);
void generateReimplementedFrom(const FunctionNode *func, CodeMarker *marker);
QString amp;
diff --git a/src/tools/qdoc/helpprojectwriter.cpp b/src/tools/qdoc/helpprojectwriter.cpp
index 0cdb2de776..44292f84bb 100644
--- a/src/tools/qdoc/helpprojectwriter.cpp
+++ b/src/tools/qdoc/helpprojectwriter.cpp
@@ -135,6 +135,7 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["qmlsignal"] = Node::QmlSignal;
typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
typeHash["qmlmethod"] = Node::QmlMethod;
+ typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
QHash<QString, Node::SubType> subTypeHash;
subTypeHash["example"] = Node::Example;
@@ -145,7 +146,6 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
subTypeHash["page"] = Node::Page;
subTypeHash["externalpage"] = Node::ExternalPage;
subTypeHash["qmlclass"] = Node::QmlClass;
- subTypeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
subTypeHash["qmlbasictype"] = Node::QmlBasicType;
QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
@@ -225,7 +225,7 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
details << node->name();
details << node->name();
}
- details << gen_->fullDocumentLocation(node,true);
+ details << gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
return details;
}
@@ -285,12 +285,12 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Class:
project.keywords.append(keywordDetails(node));
- project.files.insert(gen_->fullDocumentLocation(node,true));
+ project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
break;
case Node::Namespace:
project.keywords.append(keywordDetails(node));
- project.files.insert(gen_->fullDocumentLocation(node,true));
+ project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
break;
case Node::Enum:
@@ -310,7 +310,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
details << item.name(); // "name"
details << item.name(); // "id"
}
- details << gen_->fullDocumentLocation(node,true);
+ details << gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
project.keywords.append(details);
}
}
@@ -342,7 +342,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
if (node->relates()) {
project.memberStatus[node->relates()].insert(node->status());
- project.files.insert(gen_->fullDocumentLocation(node->relates(),true));
+ project.files.insert(gen_->fullDocumentLocation(node->relates(),Generator::useOutputSubdirs()));
} else if (node->parent())
project.memberStatus[node->parent()].insert(node->status());
}
@@ -356,7 +356,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
// Use the location of any associated enum node in preference
// to that of the typedef.
if (enumNode)
- typedefDetails[2] = gen_->fullDocumentLocation(enumNode,true);
+ typedefDetails[2] = gen_->fullDocumentLocation(enumNode,Generator::useOutputSubdirs());
project.keywords.append(typedefDetails);
}
@@ -364,7 +364,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Variable:
{
- QString location = gen_->fullDocumentLocation(node,true);
+ QString location = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
project.files.insert(location.left(location.lastIndexOf(QLatin1Char('#'))));
project.keywords.append(keywordDetails(node));
}
@@ -385,18 +385,18 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
QStringList details;
details << keyword->string()
<< keyword->string()
- << gen_->fullDocumentLocation(node,true) +
+ << gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()) +
QLatin1Char('#') + Doc::canonicalTitle(keyword->string());
project.keywords.append(details);
} else
docNode->doc().location().warning(
- tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node,true))
+ tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()))
);
}
}
project.keywords.append(keywordDetails(node));
}
- project.files.insert(gen_->fullDocumentLocation(node,true));
+ project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
}
break;
}
@@ -422,6 +422,11 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
void HelpProjectWriter::generateSections(HelpProject &project,
QXmlStreamWriter &writer, const Node *node)
{
+ /*
+ Don't include index nodes in the help file. Or DITA map nodes.
+ */
+ if (node->isIndexNode() || node->subType() == Node::DitaMap)
+ return;
if (!generateSection(project, writer, node))
return;
@@ -431,29 +436,40 @@ void HelpProjectWriter::generateSections(HelpProject &project,
// Ensure that we don't visit nodes more than once.
QMap<QString, const Node*> childMap;
foreach (const Node *childNode, inner->childNodes()) {
+ if (childNode->isIndexNode())
+ continue;
+
if (childNode->access() == Node::Private)
continue;
if (childNode->type() == Node::Document) {
+ childMap[static_cast<const DocNode *>(childNode)->fullTitle()] = childNode;
+ }
+ else if (childNode->type() == Node::QmlPropertyGroup) {
/*
Don't visit QML property group nodes,
but visit their children, which are all
QML property nodes.
+
+ This is probably not correct anymore,
+ because The Qml Property Group is an
+ actual documented thing.
*/
- if (childNode->subType() == Node::QmlPropertyGroup) {
- const InnerNode* inner = static_cast<const InnerNode*>(childNode);
- foreach (const Node* n, inner->childNodes()) {
- if (n->access() == Node::Private)
- continue;
- childMap[n->fullDocumentName()] = n;
- }
+ const InnerNode* inner = static_cast<const InnerNode*>(childNode);
+ foreach (const Node* n, inner->childNodes()) {
+ if (n->access() == Node::Private)
+ continue;
+ childMap[n->fullDocumentName()] = n;
}
- else
- childMap[static_cast<const DocNode *>(childNode)->fullTitle()] = childNode;
}
else {
// Store member status of children
project.memberStatus[node].insert(childNode->status());
+ if (childNode->relates()) {
+ project.memberStatus[childNode->relates()].insert(childNode->status());
+ project.files.insert(gen_->fullDocumentLocation(childNode->relates(),
+ Generator::useOutputSubdirs()));
+ }
if (childNode->type() == Node::Function) {
const FunctionNode *funcNode = static_cast<const FunctionNode *>(childNode);
@@ -508,7 +524,7 @@ void HelpProjectWriter::writeSection(QXmlStreamWriter &writer, const QString &pa
void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &writer,
const Node *node, bool writeSections)
{
- QString href = gen_->fullDocumentLocation(node,true);
+ QString href = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
href = href.left(href.size()-5);
if (href.isEmpty())
return;
@@ -546,7 +562,7 @@ void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &write
void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer,
const Node *node)
{
- QString href = gen_->fullDocumentLocation(node,true);
+ QString href = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
QString objName = node->name();
switch (node->type()) {
@@ -642,7 +658,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
node = qdb_->findNode(QStringList("index.html"));
QString indexPath;
if (node)
- indexPath = gen_->fullDocumentLocation(node,true);
+ indexPath = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
else
indexPath = "index.html";
writer.writeAttribute("ref", indexPath);
@@ -685,7 +701,8 @@ void HelpProjectWriter::generateProject(HelpProject &project)
const DocNode *page = qdb_->findDocNodeByTitle(atom->string());
writer.writeStartElement("section");
- QString indexPath = gen_->fullDocumentLocation(page,true);
+ QString indexPath = gen_->fullDocumentLocation(page,
+ Generator::useOutputSubdirs());
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", atom->string());
project.files.insert(indexPath);
@@ -710,7 +727,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
if (!name.isEmpty()) {
writer.writeStartElement("section");
- QString indexPath = gen_->fullDocumentLocation(qdb_->findDocNodeByTitle(subproject.indexTitle),true);
+ QString indexPath = gen_->fullDocumentLocation(qdb_->findDocNodeByTitle(subproject.indexTitle),Generator::useOutputSubdirs());
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", subproject.title);
project.files.insert(indexPath);
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index 7cb56974d5..52af5d60b9 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -166,9 +166,9 @@ void HtmlGenerator::initializeGenerator(const Config &config)
pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() +
Config::dot +
HTMLGENERATOR_GENERATEMACREFS);
- noBreadCrumbs = config.getBool(HtmlGenerator::format() +
+ noNavigationBar = config.getBool(HtmlGenerator::format() +
Config::dot +
- HTMLGENERATOR_NOBREADCRUMBS);
+ HTMLGENERATOR_NONAVIGATIONBAR);
project = config.getString(CONFIG_PROJECT);
@@ -229,6 +229,25 @@ void HtmlGenerator::initializeGenerator(const Config &config)
examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH);
if (!examplesPath.isEmpty())
examplesPath += QLatin1Char('/');
+
+ //retrieve the config for the navigation bar
+ homepage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_HOMEPAGE);
+
+ landingpage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_LANDINGPAGE);
+
+ cppclassespage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_CPPCLASSESPAGE);
+
+ qmltypespage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_QMLTYPESPAGE);
+
+ buildversion = config.getString(CONFIG_BUILDVERSION);
}
/*!
@@ -1095,8 +1114,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
QList<Section> sections;
QList<Section>::ConstIterator s;
- ClassNode* classe = 0;
-
QString title;
QString rawTitle;
QString fullTitle;
@@ -1106,7 +1123,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
title = rawTitle + " Namespace";
}
else if (inner->type() == Node::Class) {
- classe = static_cast<ClassNode*>(inner);
rawTitle = inner->plainName();
fullTitle = inner->plainFullName();
title = rawTitle + " Class";
@@ -1121,16 +1137,9 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
generateTableOfContents(inner,marker,&sections);
generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
generateBrief(inner, marker);
- generateIncludes(inner, marker);
+ generateRequisites(inner, marker);
generateStatus(inner, marker);
- if (classe) {
- generateInherits(classe, marker);
- generateInheritedBy(classe, marker);
- if (classe->qmlElement() != 0)
- generateInstantiatedBy(classe,marker);
- }
generateThreadSafeness(inner, marker);
- generateSince(inner, marker);
out() << "<ul>\n";
@@ -1511,10 +1520,7 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
const_cast<DocNode*>(dn)->setCurrentChild();
ClassNode* cn = qml_cn->classNode();
generateBrief(qml_cn, marker);
- generateQmlInherits(qml_cn, marker);
- generateQmlInheritedBy(qml_cn, marker);
- generateQmlInstantiates(qml_cn, marker);
- generateSince(qml_cn, marker);
+ generateQmlRequisites(qml_cn, marker);
QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker);
if (!allQmlMembersLink.isEmpty()) {
@@ -1616,129 +1622,67 @@ QString HtmlGenerator::fileExtension() const
}
/*!
- Output breadcrumb list in the html file.
+ Output navigation list in the html file.
*/
-void HtmlGenerator::generateBreadCrumbs(const QString &title,
+void HtmlGenerator::generateNavigationBar(const QString &title,
const Node *node,
CodeMarker *marker)
{
- if (noBreadCrumbs)
+ if (noNavigationBar)
return;
- Text breadcrumbs;
+ Text navigationbar;
+
+ if (homepage == title)
+ return;
+ if (!homepage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::AutoLink, homepage)
+ << Atom(Atom::ListItemRight);
+ if (!landingpage.isEmpty() && landingpage != title)
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::AutoLink, landingpage)
+ << Atom(Atom::ListItemRight);
+
if (node->type() == Node::Class) {
const ClassNode *cn = static_cast<const ClassNode *>(node);
QString name = node->moduleName();
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Modules"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Modules"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- if (!name.isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, name)
+
+ if (!cppclassespage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::Link, cppclassespage)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, QLatin1String("C++ Classes"))
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
<< Atom(Atom::ListItemRight);
+
if (!cn->name().isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
+ navigationbar << Atom(Atom::ListItemLeft)
<< Atom(Atom::String, protectEnc(cn->name()))
<< Atom(Atom::ListItemRight);
}
else if (node->type() == Node::Document) {
- const DocNode* fn = static_cast<const DocNode*>(node);
- if (node->subType() == Node::Module) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Modules"))
+ if (node->subType() == Node::QmlClass || node->subType() == Node::QmlBasicType) {
+ if (!qmltypespage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::Link, qmltypespage)
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Modules"))
+ << Atom(Atom::String, QLatin1String("QML Types"))
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
<< Atom(Atom::ListItemRight);
- QString name = node->name();
- if (!name.isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(name))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::Group) {
- if (fn->name() == QString("modules"))
- breadcrumbs << Atom(Atom::String, QLatin1String("Modules"));
- else
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::Page) {
- if (fn->name() == QString("qdeclarativeexamples.html")) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("QML Examples & Demos"))
- << Atom(Atom::ListItemRight);
- }
- else if (fn->name().startsWith("examples-")) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (fn->name() == QString("namespaces.html"))
- breadcrumbs << Atom(Atom::String, QLatin1String("Namespaces"));
- else
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::QmlClass) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("Basic QML Types"))
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
+
+ navigationbar << Atom(Atom::ListItemLeft)
<< Atom(Atom::String, protectEnc(title))
<< Atom(Atom::ListItemRight);
}
- else if (node->subType() == Node::Example) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- QStringList sl = fn->name().split('/');
- if (sl.contains("declarative"))
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("QML Examples & Demos"))
- << Atom(Atom::ListItemRight);
- else {
- QString name = protectEnc("examples-" + sl.at(0) + ".html"); // this generates an empty link
- QString t = CodeParser::titleFromName(name);
- }
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
+ else {
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::String, protectEnc(title))
+ << Atom(Atom::ListItemRight);
}
}
- else if (node->type() == Node::Namespace) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Namespaces"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Namespaces"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- generateText(breadcrumbs, node, marker);
+ generateText(navigationbar, node, marker);
}
void HtmlGenerator::generateHeader(const QString& title,
@@ -1782,7 +1726,8 @@ void HtmlGenerator::generateHeader(const QString& title,
#endif
out() << QString(postHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
- generateBreadCrumbs(title,node,marker);
+ generateNavigationBar(title,node,marker);
+ out() << "<li id=\"buildversion\">\n" << buildversion << "</li>\n";
out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
navigationLinks.clear();
@@ -1881,6 +1826,273 @@ void HtmlGenerator::generateFooter(const Node *node)
out() << "</html>\n";
}
+/*!
+Lists the required imports and includes in a table.
+The number of rows is known, so this path is simpler than the generateSection() path.
+*/
+void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
+{
+ QMap<QString, Text> requisites;
+ Text text;
+
+ const QString headerText = "Header";
+ const QString sinceText = "Since";
+ const QString inheritedBytext = "Inherited By";
+ const QString inheritsText = "Inherits";
+ const QString instantiatedByText = "Instantiated By";
+ const QString qtVariableText = "qmake";
+
+ //add the includes to the map
+ if (!inner->includes().isEmpty()) {
+ text.clear();
+ text << formattingRightMap()[ATOM_FORMATTING_BOLD]
+ << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
+ << highlightedCode(indent(codeIndent,
+ marker->markedUpIncludes(inner->includes())),
+ inner)
+ << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ requisites.insert(headerText, text);
+ }
+
+ //The order of the requisites matter
+ QStringList requisiteorder;
+ requisiteorder << headerText
+ << qtVariableText
+ << sinceText
+ << instantiatedByText
+ << inheritsText
+ << inheritedBytext;
+
+ //add the since and project into the map
+ if (!inner->since().isEmpty()) {
+ text.clear();
+ QStringList since = inner->since().split(QLatin1Char(' '));
+ if (since.count() == 1) {
+ // Handle legacy use of \since <version>.
+ if (project.isEmpty())
+ text << "version";
+ else
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << " " << since[0];
+ }
+ else {
+ // Reconstruct the <project> <version> string.
+ text << " " << since.join(' ');
+ }
+ text << Atom::ParaRight;
+ requisites.insert(sinceText, text);
+ }
+
+ if (inner->type() == Node::Class || inner->type() == Node::Namespace) {
+ //add the QT variable to the map
+ if (!inner->moduleName().isEmpty()) {
+ DocNode * moduleNode = qdb_->findModule(inner->moduleName());
+ if (moduleNode && !moduleNode->qtVariable().isEmpty()) {
+ text.clear();
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_TELETYPE)
+ << "QT += " + moduleNode->qtVariable()
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_TELETYPE);
+ requisites.insert(qtVariableText, text);
+ }
+ }
+ }
+
+ if (inner->type() == Node::Class) {
+ ClassNode* classe = static_cast<ClassNode*>(inner);
+ if (classe->qmlElement() != 0 && classe->status() != Node::Internal) {
+ text.clear();
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode(classe->qmlElement()))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, classe->qmlElement()->name())
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ requisites.insert(instantiatedByText, text);
+
+ }
+
+ //add the inherits to the map
+ QList<RelatedClass>::ConstIterator r;
+ int index;
+ if (!classe->baseClasses().isEmpty()) {
+ text.clear();
+ r = classe->baseClasses().constBegin();
+ index = 0;
+ while (r != classe->baseClasses().constEnd()) {
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, (*r).dataTypeWithTemplateArgs)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ if ((*r).access == Node::Protected) {
+ text << " (protected)";
+ }
+ else if ((*r).access == Node::Private) {
+ text << " (private)";
+ }
+ text << separator(index++, classe->baseClasses().count());
+ ++r;
+ }
+ text << Atom::ParaRight;
+ requisites.insert(inheritsText, text);
+ }
+
+ //add the inherited-by to the map
+ if (!classe->derivedClasses().isEmpty()) {
+ text.clear();
+ text << Atom::ParaLeft;
+ appendSortedNames(text, classe, classe->derivedClasses());
+ text << Atom::ParaRight;
+ requisites.insert(inheritedBytext, text);
+ }
+ }
+
+ if (!requisites.isEmpty()) {
+ //generate the table
+ out() << "<table class=\"alignedsummary\">\n";
+
+ QStringList::ConstIterator i;
+ for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
+
+ if (requisites.contains(*i)) {
+ out() << "<tr>"
+ << "<td class=\"memItemLeft rightAlign topAlign\"> "
+ << *i << ":"
+ << "</td><td class=\"memItemRight bottomAlign\"> ";
+
+ if (*i == headerText)
+ out() << requisites.value(*i).toString();
+ else
+ generateText(requisites.value(*i), inner, marker);
+ out() << "</td></tr>";
+ }
+ }
+ out() << "</table>";
+ }
+}
+
+/*!
+Lists the required imports and includes in a table.
+The number of rows is known, so this path is simpler than the generateSection() path.
+*/
+void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker)
+{
+ if (!qcn)
+ return;
+ QMap<QString, Text> requisites;
+ Text text;
+
+ const QString importText = "Import Statement:";
+ const QString sinceText = "Since:";
+ const QString inheritedBytext = "Inherited By:";
+ const QString inheritsText = "Inherits:";
+ const QString instantiatesText = "Instantiates:";
+
+ //The order of the requisites matter
+ QStringList requisiteorder;
+ requisiteorder << importText
+ << sinceText
+ << instantiatesText
+ << inheritsText
+ << inheritedBytext;
+
+ //add the module name and version to the map
+ text.clear();
+ text << formattingRightMap()[ATOM_FORMATTING_BOLD]
+ << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
+ << "import " + qcn->qmlModuleName() + " " + qcn->qmlModuleVersion()
+ << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ requisites.insert(importText, text);
+
+ //add the since and project into the map
+ if (!qcn->since().isEmpty()) {
+ text.clear();
+ QStringList since = qcn->since().split(QLatin1Char(' '));
+ if (since.count() == 1) {
+ // Handle legacy use of \since <version>.
+ if (project.isEmpty())
+ text << "version";
+ else
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ text << " " << since[0];
+ }
+ else {
+ // Reconstruct the <project> <version> string.
+ text << " " << since.join(' ');
+ }
+ text << Atom::ParaRight;
+ requisites.insert(sinceText, text);
+ }
+
+ //add the instantiates to the map
+ ClassNode* cn = qcn->classNode();
+ if (cn && (cn->status() != Node::Internal)) {
+ text.clear();
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, cn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ requisites.insert(instantiatesText, text);
+ }
+
+ //add the inherits to the map
+ const QmlClassNode* base = qcn->qmlBaseNode();
+ while (base && base->isInternal()) {
+ base = base->qmlBaseNode();
+ }
+ if (base) {
+ text.clear();
+ text << Atom::ParaLeft
+ << Atom(Atom::LinkNode,CodeMarker::stringForNode(base))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, base->name())
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
+ << Atom::ParaRight;
+ requisites.insert(inheritsText, text);
+ }
+
+ //add the inherited-by to the map
+ NodeList subs;
+ QmlClassNode::subclasses(qcn->name(), subs);
+ if (!subs.isEmpty()) {
+ text.clear();
+ text << Atom::ParaLeft;
+ appendSortedQmlNames(text, qcn, subs);
+ text << Atom::ParaRight;
+ requisites.insert(inheritedBytext, text);
+ }
+
+ if (!requisites.isEmpty()) {
+ //generate the table
+ out() << "<table class=\"alignedsummary\">\n";
+
+ QStringList::ConstIterator i;
+ for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
+
+ if (requisites.contains(*i)) {
+ out() << "<tr>"
+ << "<td class=\"memItemLeft rightAlign topAlign\"> "
+ << *i
+ << "</td><td class=\"memItemRight bottomAlign\"> ";
+
+ if (*i == importText)
+ out()<<requisites.value(*i).toString();
+ else
+ generateText(requisites.value(*i), qcn, marker);
+ out() << "</td></tr>";
+ }
+ }
+ out() << "</table>";
+ }
+}
+
void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
const Node *relative)
{
@@ -2151,7 +2363,10 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner,
fileName = fileBase(inner) + "-obsolete." + fileExtension();
}
if (status == CodeMarker::Obsolete) {
- QString link = QString("../" + Generator::outputSubdir() + QLatin1Char('/')) + fileName;
+ QString link;
+ if (useOutputSubdirs() && !Generator::outputSubdir().isEmpty())
+ link = QString("../" + Generator::outputSubdir() + QLatin1Char('/'));
+ link += fileName;
inner->setObsoleteLink(link);
}
@@ -2160,21 +2375,22 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner,
generateTitle(title, Text(), SmallSubTitle, inner, marker);
if (status == CodeMarker::Compat) {
- out() << "<p><b>The following class members are part of the "
+ out() << "<p><b>The following members of class "
+ << "<a href=\"" << linkForNode(inner, 0) << "\">"
+ << protectEnc(inner->name()) << "</a>"
+ << "are part of the "
"Qt compatibility layer.</b> We advise against "
"using them in new code.</p>\n";
}
else {
- out() << "<p><b>The following class members are obsolete.</b> "
+ out() << "<p><b>The following members of class "
+ << "<a href=\"" << linkForNode(inner, 0) << "\">"
+ << protectEnc(inner->name()) << "</a>"
+ << " are obsolete.</b> "
<< "They are provided to keep old source code working. "
<< "We strongly advise against using them in new code.</p>\n";
}
- out() << "<p><ul><li><a href=\""
- << linkForNode(inner, 0) << "\">"
- << protectEnc(inner->name())
- << " class reference</a></li></ul></p>\n";
-
for (i = 0; i < sections.size(); ++i) {
out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
@@ -2492,8 +2708,10 @@ void HtmlGenerator::generateCompactList(ListType listType,
}
else if (listType == Obsolete) {
QString fileName = fileBase(it.value()) + "-obsolete." + fileExtension();
- QString link = QString("../" + it.value()->outputSubdirectory() +
- QLatin1Char('/')) + fileName;
+ QString link;
+ if (useOutputSubdirs())
+ link = QString("../" + it.value()->outputSubdirectory() + QLatin1Char('/'));
+ link += fileName;
out() << "<a href=\"" << link << "\">";
}
@@ -3308,8 +3526,8 @@ QString HtmlGenerator::refForNode(const Node *node)
}
break;
case Node::Document:
- if (node->subType() != Node::QmlPropertyGroup)
- break;
+ break;
+ case Node::QmlPropertyGroup:
case Node::QmlProperty:
case Node::Property:
ref = node->name() + "-prop";
@@ -3372,7 +3590,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
}
QString link = fn;
- if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
+ if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
QString ref = refForNode(node);
if (relative && fn == fileName(relative) && ref == refForNode(relative))
return QString();
@@ -3387,7 +3605,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
back down into the other subdirectory.
*/
if (node && relative && (node != relative)) {
- if (node->outputSubdirectory() != relative->outputSubdirectory())
+ if (useOutputSubdirs() && node->outputSubdirectory() != relative->outputSubdirectory())
link.prepend(QString("../" + node->outputSubdirectory() + QLatin1Char('/')));
}
return link;
@@ -3778,6 +3996,22 @@ void HtmlGenerator::generateQmlSummary(const Section& section,
while (m != section.members.constEnd()) {
out() << "<li class=\"fn\">";
generateQmlItem(*m,relative,marker,true);
+ if ((*m)->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*m);
+ if (!qpgn->childNodes().isEmpty()) {
+ NodeList::ConstIterator p = qpgn->childNodes().constBegin();
+ out() << "<ul>\n";
+ while (p != qpgn->childNodes().constEnd()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ out() << "<li class=\"fn\">";
+ generateQmlItem(*p, relative, marker, true);
+ out() << "</li>\n";
+ }
+ ++p;
+ }
+ out() << "</ul>\n";
+ }
+ }
out() << "</li>\n";
++m;
}
@@ -3799,11 +4033,18 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
#endif
generateExtractionMark(node, MemberMark);
out() << "<div class=\"qmlitem\">";
- if (node->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ if (node->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
out() << "<div class=\"qmlproto\">";
out() << "<table class=\"qmlname\">";
+
+ QString heading = qpgn->name() + " group";
+ out() << "<tr valign=\"top\" class=\"even\">";
+ out() << "<th class=\"centerAlign\"><p>";
+ out() << "<a name=\"" + refForNode(qpgn) + "\"></a>";
+ out() << "<b>" << heading << "</b>";
+ out() << "</p></th></tr>";
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(*p);
@@ -3825,68 +4066,23 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
}
else if (node->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(node);
- /*
- If the QML property node has a single subproperty,
- override, replace qpn with that override node and
- proceed as normal.
- */
- if (qpn->qmlPropNodes().size() == 1) {
- Node* n = qpn->qmlPropNodes().at(0);
- if (n->type() == Node::QmlProperty)
- qpn = static_cast<QmlPropertyNode*>(n);
- }
- /*
- Now qpn either has no overrides, or it has more
- than 1. If it has none, proceed to output as nortmal.
- */
- if (qpn->qmlPropNodes().isEmpty()) {
- out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
- out() << "<tr valign=\"top\" class=\"odd\">";
- out() << "<td class=\"tblQmlPropNode\"><p>";
- out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
- if (!qpn->isReadOnlySet()) {
- if (qpn->declarativeCppNode())
- qpn->setReadOnly(!qpn->isWritable(qdb_));
- }
- if (qpn->isReadOnly())
- out() << "<span class=\"qmlreadonly\">read-only</span>";
- if (qpn->isDefault())
- out() << "<span class=\"qmldefault\">default</span>";
- generateQmlItem(qpn, relative, marker, false);
- out() << "</p></td></tr>";
- out() << "</table>";
- out() << "</div>";
- }
- else {
- /*
- The QML property node has multiple override nodes.
- Process the whole list as we would for a QML property
- group.
- */
- NodeList::ConstIterator p = qpn->qmlPropNodes().constBegin();
- out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
- while (p != qpn->qmlPropNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p);
- out() << "<tr valign=\"top\" class=\"odd\">";
- out() << "<td class=\"tblQmlPropNode\"><p>";
- out() << "<a name=\"" + refForNode(q) + "\"></a>";
- if (!qpn->isReadOnlySet())
- qpn->setReadOnly(!qpn->isWritable(qdb_));
- if (qpn->isReadOnly())
- out() << "<span class=\"qmlreadonly\">read-only</span>";
- if (qpn->isDefault())
- out() << "<span class=\"qmldefault\">default</span>";
- generateQmlItem(q, relative, marker, false);
- out() << "</p></td></tr>";
- }
- ++p;
- }
- out() << "</table>";
- out() << "</div>";
- }
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+ out() << "<tr valign=\"top\" class=\"odd\">";
+ out() << "<td class=\"tblQmlPropNode\"><p>";
+ out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
+ if (!qpn->isReadOnlySet()) {
+ if (qpn->declarativeCppNode())
+ qpn->setReadOnly(!qpn->isWritable(qdb_));
+ }
+ if (qpn->isReadOnly())
+ out() << "<span class=\"qmlreadonly\">read-only</span>";
+ if (qpn->isDefault())
+ out() << "<span class=\"qmldefault\">default</span>";
+ generateQmlItem(qpn, relative, marker, false);
+ out() << "</p></td></tr>";
+ out() << "</table>";
+ out() << "</div>";
}
else if (node->type() == Node::QmlSignal) {
const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
@@ -4359,8 +4555,6 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
break;
case Node::QmlClass:
break;
- case Node::QmlPropertyGroup:
- break;
case Node::QmlBasicType:
break;
case Node::QmlModule:
@@ -4394,6 +4588,8 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
if (!related)
child->location().warning(tr("Global variable, %1, %2").arg(child->name()).arg(message));
break;
+ case Node::QmlPropertyGroup:
+ break;
case Node::QmlProperty:
if (!related)
child->location().warning(tr("Global QML property, %1, %2").arg(child->name()).arg(message));
diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h
index 0a6717461e..8cd8664dfc 100644
--- a/src/tools/qdoc/htmlgenerator.h
+++ b/src/tools/qdoc/htmlgenerator.h
@@ -127,7 +127,7 @@ private:
};
const QPair<QString,QString> anchorForNode(const Node *node);
- void generateBreadCrumbs(const QString& title,
+ void generateNavigationBar(const QString& title,
const Node *node,
CodeMarker *marker);
void generateHeader(const QString& title,
@@ -139,6 +139,10 @@ private:
const Node *relative,
CodeMarker *marker);
void generateFooter(const Node *node = 0);
+ void generateRequisites(InnerNode *inner,
+ CodeMarker *marker);
+ void generateQmlRequisites(QmlClassNode *qcn,
+ CodeMarker *marker);
void generateBrief(const Node *node,
CodeMarker *marker,
const Node *relative = 0);
@@ -182,6 +186,7 @@ private:
void generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker);
void generateInstantiatedBy(ClassNode* cn, CodeMarker* marker);
+ void generateRequisitesTable(const QStringList& requisitesOrder, QMap<QString, Text>& requisites);
void generateSection(const NodeList& nl,
const Node *relative,
CodeMarker *marker,
@@ -239,7 +244,7 @@ private:
QString footer;
QString address;
bool pleaseGenerateMacRef;
- bool noBreadCrumbs;
+ bool noNavigationBar;
QString project;
QString projectDescription;
QString projectUrl;
@@ -252,6 +257,12 @@ private:
QStack<QXmlStreamWriter*> xmlWriterStack;
static int id;
QList<ManifestMetaFilter> manifestMetaContent;
+ QString homepage;
+ QString landingpage;
+ QString cppclassespage;
+ QString qmltypespage;
+ QString buildversion;
+
public:
static bool debugging_on;
static QString divNavTop;
@@ -262,9 +273,10 @@ public:
#define HTMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
#define HTMLGENERATOR_POSTHEADER "postheader"
#define HTMLGENERATOR_POSTPOSTHEADER "postpostheader"
-#define HTMLGENERATOR_NOBREADCRUMBS "nobreadcrumbs"
+#define HTMLGENERATOR_NONAVIGATIONBAR "nonavigationbar"
+#define HTMLGENERATOR_NOSUBDIRS "nosubdirs"
+
QT_END_NAMESPACE
#endif
-
diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp
index 3ec121f795..912cdad7eb 100644
--- a/src/tools/qdoc/main.cpp
+++ b/src/tools/qdoc/main.cpp
@@ -95,6 +95,7 @@ bool creationTimeBefore(const QFileInfo &fi1, const QFileInfo &fi2)
static bool highlighting = false;
static bool showInternal = false;
+static bool redirectDocumentationToDevNull = false;
static bool noLinkErrors = false;
static bool obsoleteLinks = false;
static QStringList defines;
@@ -139,6 +140,8 @@ static void printHelp()
"Run qdoc to read the index files and generate the docs\n"
" -showinternal "
"Include content marked internal\n"
+ " -redirect-documentation-to-dev-null "
+ "Save all documentation content to /dev/null. Useful if someone is interested in qdoc errors only.\n"
" -version "
"Display version of qdoc and exit\n") );
}
@@ -162,6 +165,15 @@ static void loadIndexFiles(Config& config)
dependModules += config.getStringList(CONFIG_DEPENDS);
+ bool noOutputSubdirs = false;
+ QString singleOutputSubdir;
+ if (config.getBool(QString("HTML.nosubdirs"))) {
+ noOutputSubdirs = true;
+ singleOutputSubdir = config.getString("HTML.outputsubdir");
+ if (singleOutputSubdir.isEmpty())
+ singleOutputSubdir = "html";
+ }
+
// Allow modules and third-party application/libraries to link
// to the Qt docs without having to explicitly pass --indexdir.
if (!indexDirs.contains(documentationPath))
@@ -196,8 +208,12 @@ static void loadIndexFiles(Config& config)
QString indexToAdd;
QList<QFileInfo> foundIndices;
for (int j = 0; j < indexDirs.size(); j++) {
- QString fileToLookFor = indexDirs[j] + QLatin1Char('/') + dependModules[i] +
- QLatin1Char('/') + dependModules[i] + QLatin1String(".index");
+ QString fileToLookFor = indexDirs[j] + QLatin1Char('/');
+ if (noOutputSubdirs)
+ fileToLookFor += singleOutputSubdir + QLatin1Char('/');
+ else
+ fileToLookFor += dependModules[i] + QLatin1Char('/');
+ fileToLookFor += dependModules[i] + QLatin1String(".index");
if (QFile::exists(fileToLookFor)) {
QFileInfo tempFileInfo(fileToLookFor);
if (!foundIndices.contains(tempFileInfo))
@@ -257,6 +273,7 @@ static void processQdocconfFile(const QString &fileName)
}
config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false"));
config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false"));
+ config.setStringList(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL, QStringList(redirectDocumentationToDevNull ? "true" : "false"));
config.setStringList(CONFIG_NOLINKERRORS, QStringList(noLinkErrors ? "true" : "false"));
config.setStringList(CONFIG_OBSOLETELINKS, QStringList(obsoleteLinks ? "true" : "false"));
@@ -573,6 +590,9 @@ int main(int argc, char **argv)
else if (opt == "-showinternal") {
showInternal = true;
}
+ else if (opt == "-redirect-documentation-to-dev-null") {
+ redirectDocumentationToDevNull = true;
+ }
else if (opt == "-no-examples") {
Config::generateExamples = false;
}
diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp
index 2184e302ae..fd56c77742 100644
--- a/src/tools/qdoc/node.cpp
+++ b/src/tools/qdoc/node.cpp
@@ -151,11 +151,11 @@ QString Node::fullName(const Node* relative) const
*/
void Node::setDoc(const Doc& doc, bool replace)
{
- if (!d.isEmpty() && !replace) {
+ if (!doc_.isEmpty() && !replace) {
doc.location().warning(tr("Overrides a previous doc"));
- d.location().warning(tr("(The previous doc is here)"));
+ doc_.location().warning(tr("(The previous doc is here)"));
}
- d = doc;
+ doc_ = doc;
}
/*!
@@ -311,6 +311,8 @@ QString Node::nodeTypeString(unsigned t)
return "variable";
case QmlProperty:
return "QML property";
+ case QmlPropertyGroup:
+ return "QML property group";
case QmlSignal:
return "QML signal";
case QmlSignalHandler:
@@ -359,8 +361,6 @@ QString Node::nodeSubtypeString(unsigned t)
return "external page";
case QmlClass:
return "QML type";
- case QmlPropertyGroup:
- return "QML property group";
case QmlBasicType:
return "QML basic type";
case QmlModule:
@@ -742,12 +742,12 @@ void InnerNode::getMemberClasses(NodeMap& out)
Node *InnerNode::findChildNodeByName(const QString& name)
{
Node *node = childMap.value(name);
- if (node && node->subType() != QmlPropertyGroup)
+ if (node && node->type() != QmlPropertyGroup)
return node;
if ((type() == Document) && (subType() == QmlClass)) {
for (int i=0; i<children_.size(); ++i) {
Node* n = children_.at(i);
- if (n->subType() == QmlPropertyGroup) {
+ if (n->type() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(n)->findChildNodeByName(name);
if (node)
return node;
@@ -771,7 +771,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n)
if ((type() == Document) && (subType() == QmlClass)) {
for (int i=0; i<children_.size(); ++i) {
node = children_.at(i);
- if (node->subType() == QmlPropertyGroup) {
+ if (node->type() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
if (node) {
n.append(node);
@@ -793,7 +793,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n)
*/
for (int i=0; i<nodes.size(); ++i) {
node = nodes.at(i);
- if (node->subType() != QmlPropertyGroup)
+ if (node->type() != QmlPropertyGroup)
n.append(node);
else {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
@@ -829,14 +829,14 @@ Node* InnerNode::findChildNodeByName(const QString& name, bool qml)
if (!node->isQmlNode())
return node;
}
- else if (node->isQmlNode() && (node->subType() != QmlPropertyGroup))
+ else if (node->isQmlNode() && (node->type() != QmlPropertyGroup))
return node;
}
}
if (qml && (type() == Document) && (subType() == QmlClass)) {
for (int i=0; i<children_.size(); ++i) {
Node* node = children_.at(i);
- if (node->subType() == QmlPropertyGroup) {
+ if (node->type() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
if (node)
return node;
@@ -1371,6 +1371,26 @@ void InnerNode::removeRelated(Node *pseudoChild)
}
/*!
+ If this node has a child that is a QML property named \a n,
+ return the pointer to that child.
+ */
+QmlPropertyNode* InnerNode::hasQmlProperty(const QString& n) const
+{
+ foreach (Node* child, childNodes()) {
+ if (child->type() == Node::QmlProperty) {
+ if (child->name() == n)
+ return static_cast<QmlPropertyNode*>(child);
+ }
+ else if (child->type() == Node::QmlPropertyGroup) {
+ QmlPropertyNode* t = child->hasQmlProperty(n);
+ if (t)
+ return t;
+ }
+ }
+ return 0;
+}
+
+/*!
\class LeafNode
*/
@@ -1673,25 +1693,6 @@ QString DocNode::subTitle() const
}
/*!
- Returns true if this QML type or property group contains a
- property named \a name.
- */
-bool DocNode::hasProperty(const QString& name) const
-{
- foreach (Node* child, childNodes()) {
- if (child->type() == Node::Document && child->subType() == Node::QmlPropertyGroup) {
- if (child->hasProperty(name))
- return true;
- }
- else if (child->type() == Node::QmlProperty) {
- if (child->hasProperty(name))
- return true;
- }
- }
- return false;
-}
-
-/*!
The constructor calls the DocNode constructor with
\a parent, \a name, and Node::Example.
*/
@@ -2273,8 +2274,8 @@ QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent,
Constructor for the Qml property group node. \a parent is
always a QmlClassNode.
*/
-QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name)
- : DocNode(parent, name, QmlPropertyGroup, Node::ApiPage)
+QmlPropertyGroupNode::QmlPropertyGroupNode(QmlClassNode* parent, const QString& name)
+ : InnerNode(QmlPropertyGroup, parent, name)
{
idNumber_ = -1;
}
@@ -2286,24 +2287,17 @@ QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name)
property group count and set the id number to the new
value.
*/
-QString QmlPropGroupNode::idNumber()
+QString QmlPropertyGroupNode::idNumber()
{
if (idNumber_ == -1)
idNumber_ = incPropertyGroupCount();
return QString().setNum(idNumber_);
}
-
/*!
- Constructor for the QML property node, when the \a parent
- is QML property group node. This constructor is only used
- for creating QML property nodes for QML elements, i.e.
- not for creating QML property nodes for QML components.
- Hopefully, this constructor will become obsolete, so don't
- use it unless one of the other two constructors can't be
- used.
+ Constructor for the QML property node.
*/
-QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
+QmlPropertyNode::QmlPropertyNode(InnerNode* parent,
const QString& name,
const QString& type,
bool attached)
@@ -2311,56 +2305,14 @@ QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
type_(type),
stored_(FlagValueDefault),
designable_(FlagValueDefault),
+ isAlias_(false),
isdefault_(false),
attached_(attached),
readOnly_(FlagValueDefault)
{
setPageType(ApiPage);
-}
-
-/*!
- Constructor for the QML property node, when the \a parent
- is a QML class node.
- */
-QmlPropertyNode::QmlPropertyNode(QmlClassNode *parent,
- const QString& name,
- const QString& type,
- bool attached)
- : LeafNode(QmlProperty, parent, name),
- type_(type),
- stored_(FlagValueDefault),
- designable_(FlagValueDefault),
- isdefault_(false),
- attached_(attached),
- readOnly_(FlagValueDefault)
-{
- setPageType(ApiPage);
-}
-
-/*!
- Constructor for the QML property node, when the \a parent
- is a QML property node. Strictly speaking, this is not the
- way QML property nodes were originally meant to be built,
- because this constructor has another QML property node as
- its parent. But this constructor is useful for documenting
- QML properties in QML components, i.e., when you override
- the definition of a property with the \e{qmlproperty}
- command. It actually uses the parent of \a parent as the
- parent.
- */
-QmlPropertyNode::QmlPropertyNode(QmlPropertyNode* parent,
- const QString& name,
- const QString& type,
- bool attached)
- : LeafNode(parent->parent(), QmlProperty, name),
- type_(type),
- stored_(FlagValueDefault),
- designable_(FlagValueDefault),
- isdefault_(false),
- attached_(attached),
- readOnly_(FlagValueDefault)
-{
- setPageType(ApiPage);
+ if (type_ == QString("alias"))
+ isAlias_ = true;
}
/*!
@@ -2450,23 +2402,6 @@ PropertyNode* QmlPropertyNode::correspondingProperty(QDocDatabase* qdb)
return 0;
}
-/*!
- Returns true if this QML type or property group contains a
- property named \a name.
- */
-bool QmlPropertyNode::hasProperty(const QString& n) const
-{
- if (name() == n)
- return true;
- foreach (Node* child, qmlPropNodes()) {
- if (child->type() == Node::QmlProperty) {
- if (child->name() == n)
- return true;
- }
- }
- return false;
-}
-
/*! \class NameCollisionNode
An instance of this node is inserted in the tree
@@ -2586,11 +2521,10 @@ QString Node::fullDocumentName() const
const Node* n = this;
do {
- if (!n->name().isEmpty() &&
- ((n->type() != Node::Document) || (n->subType() != Node::QmlPropertyGroup)))
+ if (!n->name().isEmpty() && n->type() != Node::QmlPropertyGroup)
pieces.insert(0, n->name());
- if ((n->type() == Node::Document) && (n->subType() != Node::QmlPropertyGroup)) {
+ if (n->type() == Node::Document) {
if ((n->subType() == Node::QmlClass) && !n->qmlModuleName().isEmpty())
pieces.insert(0, n->qmlModuleIdentifier());
break;
@@ -2806,12 +2740,6 @@ QString Node::idForNode() const
case Node::QmlClass:
str = "qml-class-" + name();
break;
- case Node::QmlPropertyGroup:
- {
- Node* n = const_cast<Node*>(this);
- str = "qml-propertygroup-" + n->name();
- }
- break;
case Node::Page:
case Node::Group:
case Node::Module:
@@ -2852,6 +2780,12 @@ QString Node::idForNode() const
case Node::QmlProperty:
str = "qml-property-" + name();
break;
+ case Node::QmlPropertyGroup:
+ {
+ Node* n = const_cast<Node*>(this);
+ str = "qml-propertygroup-" + n->name();
+ }
+ break;
case Node::Property:
str = "property-" + name();
break;
diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h
index bc75df2992..8364fac82f 100644
--- a/src/tools/qdoc/node.h
+++ b/src/tools/qdoc/node.h
@@ -60,6 +60,7 @@ class InnerNode;
class ExampleNode;
class QmlClassNode;
class QDocDatabase;
+class QmlPropertyNode;
typedef QList<Node*> NodeList;
typedef QMap<QString, Node*> NodeMap;
@@ -80,6 +81,7 @@ public:
Function,
Property,
Variable,
+ QmlPropertyGroup,
QmlProperty,
QmlSignal,
QmlSignalHandler,
@@ -98,7 +100,6 @@ public:
Page,
ExternalPage,
QmlClass,
- QmlPropertyGroup,
QmlBasicType,
QmlModule,
DitaMap,
@@ -163,7 +164,10 @@ public:
QString plainName() const;
QString plainFullName(const Node* relative = 0) const;
QString fullName(const Node* relative=0) const;
+ const QString& baseName() const { return baseName_; }
+ bool hasBaseName() const { return !baseName_.isEmpty(); }
+ void setBaseName(const QString& bn) { baseName_ = bn; }
void setAccess(Access access) { access_ = access; }
void setLocation(const Location& location) { loc = location; }
void setDoc(const Doc& doc, bool replace = false);
@@ -189,6 +193,8 @@ public:
void markNotSeen() { seen_ = false; }
virtual bool isInnerNode() const = 0;
+ virtual bool isExample() const { return false; }
+ virtual bool isExampleFile() const { return false; }
virtual bool isLeaf() const { return false; }
virtual bool isReimp() const { return false; }
virtual bool isFunction() const { return false; }
@@ -200,8 +206,11 @@ public:
virtual bool isQmlPropertyGroup() const { return false; }
virtual bool isCollisionNode() const { return false; }
virtual bool isAttached() const { return false; }
+ virtual bool isAlias() const { return false; }
virtual bool isGroup() const { return false; }
virtual bool isWrapper() const;
+ virtual bool isReadOnly() const { return false; }
+ virtual bool isDefault() const { return false; }
virtual void addMember(Node* ) { }
virtual bool hasMembers() const { return false; }
virtual bool hasNamespaces() const { return false; }
@@ -209,10 +218,12 @@ public:
virtual void setAbstract(bool ) { }
virtual void setWrapper() { }
virtual QString title() const { return QString(); }
- virtual bool hasProperty(const QString& ) const { return false; }
+ virtual QmlPropertyNode* hasQmlProperty(const QString& ) const { return 0; }
virtual void getMemberNamespaces(NodeMap& ) { }
virtual void getMemberClasses(NodeMap& ) { }
virtual bool isInternal() const;
+ virtual void setDataType(const QString& ) { }
+ virtual void setReadOnly(bool ) { }
bool isIndexNode() const { return indexNodeFlag_; }
bool wasSeen() const { return seen_; }
Type type() const { return nodeType_; }
@@ -231,7 +242,7 @@ public:
Access access() const { return access_; }
QString accessString() const;
const Location& location() const { return loc; }
- const Doc& doc() const { return d; }
+ const Doc& doc() const { return doc_; }
Status status() const { return status_; }
Status inheritedStatus() const;
ThreadSafeness threadSafeness() const;
@@ -294,8 +305,9 @@ private:
InnerNode* relatesTo_;
QString name_;
Location loc;
- Doc d;
+ Doc doc_;
QMap<LinkType, QPair<QString, QString> > linkMap_;
+ QString baseName_;
QString moduleName_;
QString url_;
QString since_;
@@ -366,6 +378,7 @@ public:
virtual void setCurrentChild(InnerNode* ) { }
virtual void setOutputFileName(const QString& f) { outputFileName_ = f; }
virtual QString outputFileName() const { return outputFileName_; }
+ virtual QmlPropertyNode* hasQmlProperty(const QString& ) const;
void printChildren(const QString& title);
void printMembers(const QString& title);
@@ -444,7 +457,7 @@ public:
virtual bool isClass() const { return true; }
virtual bool isWrapper() const { return wrapper_; }
virtual QString obsoleteLink() const { return obsoleteLink_; }
- virtual void setObsoleteLink(const QString& t) { obsoleteLink_ = t; };
+ virtual void setObsoleteLink(const QString& t) { obsoleteLink_ = t; }
virtual void setWrapper() { wrapper_ = true; }
void addBaseClass(Access access,
@@ -486,9 +499,11 @@ public:
PageType ptype);
virtual ~DocNode() { }
+ void setQtVariable(const QString &variable) { qtVariable_ = variable; }
void setTitle(const QString &title) { title_ = title; }
void setSubTitle(const QString &subTitle) { subtitle_ = subTitle; }
+ QString qtVariable() const { return qtVariable_; }
SubType subType() const { return nodeSubtype_; }
virtual QString title() const;
virtual QString fullTitle() const;
@@ -497,13 +512,16 @@ public:
virtual QString nameForLists() const { return title(); }
virtual void setImageFileName(const QString& ) { }
virtual bool isGroup() const { return (subType() == Node::Group); }
- virtual bool isQmlPropertyGroup() const { return (nodeSubtype_ == QmlPropertyGroup); }
- virtual bool hasProperty(const QString& ) const;
+ virtual bool isExample() const { return (subType() == Node::Example); }
+ virtual bool isExampleFile() const { return (parent() && parent()->isExample()); }
protected:
SubType nodeSubtype_;
QString title_;
QString subtitle_;
+
+private:
+ QString qtVariable_;
};
class NameCollisionNode : public DocNode
@@ -619,11 +637,11 @@ public:
virtual bool isQmlNode() const { return true; }
};
-class QmlPropGroupNode : public DocNode
+class QmlPropertyGroupNode : public InnerNode
{
public:
- QmlPropGroupNode(QmlClassNode* parent, const QString& name);
- virtual ~QmlPropGroupNode() { }
+ QmlPropertyGroupNode(QmlClassNode* parent, const QString& name);
+ virtual ~QmlPropertyGroupNode() { }
virtual bool isQmlNode() const { return true; }
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
virtual QString qmlTypeName() const { return parent()->qmlTypeName(); }
@@ -631,6 +649,7 @@ public:
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
virtual QString idNumber();
+ virtual bool isQmlPropertyGroup() const { return true; }
const QString& element() const { return parent()->name(); }
@@ -645,34 +664,27 @@ class QmlPropertyNode : public LeafNode
Q_DECLARE_TR_FUNCTIONS(QDoc::QmlPropertyNode)
public:
- QmlPropertyNode(QmlClassNode *parent,
- const QString& name,
- const QString& type,
- bool attached);
- QmlPropertyNode(QmlPropGroupNode* parent,
- const QString& name,
- const QString& type,
- bool attached);
- QmlPropertyNode(QmlPropertyNode* parent,
+ QmlPropertyNode(InnerNode *parent,
const QString& name,
const QString& type,
bool attached);
virtual ~QmlPropertyNode() { }
- void setDataType(const QString& dataType) { type_ = dataType; }
+ virtual void setDataType(const QString& dataType) { type_ = dataType; }
void setStored(bool stored) { stored_ = toFlagValue(stored); }
void setDesignable(bool designable) { designable_ = toFlagValue(designable); }
- void setReadOnly(bool ro) { readOnly_ = toFlagValue(ro); }
+ virtual void setReadOnly(bool ro) { readOnly_ = toFlagValue(ro); }
void setDefault() { isdefault_ = true; }
const QString &dataType() const { return type_; }
QString qualifiedDataType() const { return type_; }
bool isReadOnlySet() const { return (readOnly_ != FlagValueDefault); }
- bool isDefault() const { return isdefault_; }
bool isStored() const { return fromFlagValue(stored_,true); }
bool isDesignable() const { return fromFlagValue(designable_,false); }
bool isWritable(QDocDatabase* qdb);
- bool isReadOnly() const { return fromFlagValue(readOnly_,false); }
+ virtual bool isDefault() const { return isdefault_; }
+ virtual bool isReadOnly() const { return fromFlagValue(readOnly_,false); }
+ virtual bool isAlias() const { return isAlias_; }
virtual bool isAttached() const { return attached_; }
virtual bool isQmlNode() const { return true; }
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
@@ -680,22 +692,19 @@ public:
virtual QString qmlModuleName() const { return parent()->qmlModuleName(); }
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
- virtual bool hasProperty(const QString& name) const;
PropertyNode* correspondingProperty(QDocDatabase* qdb);
- const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
- void appendQmlPropNode(QmlPropertyNode* p) { qmlPropNodes_.append(p); }
- const NodeList& qmlPropNodes() const { return qmlPropNodes_; }
+ const QString& element() const { return static_cast<QmlPropertyGroupNode*>(parent())->element(); }
private:
QString type_;
FlagValue stored_;
FlagValue designable_;
+ bool isAlias_;
bool isdefault_;
bool attached_;
FlagValue readOnly_;
- NodeList qmlPropNodes_;
};
class EnumItem
@@ -892,7 +901,7 @@ public:
PropertyNode(InnerNode* parent, const QString& name);
virtual ~PropertyNode() { }
- void setDataType(const QString& dataType) { type_ = dataType; }
+ virtual void setDataType(const QString& dataType) { type_ = dataType; }
void addFunction(FunctionNode* function, FunctionRole role);
void addSignal(FunctionNode* function, FunctionRole role);
void setStored(bool stored) { stored_ = toFlagValue(stored); }
diff --git a/src/tools/qdoc/puredocparser.cpp b/src/tools/qdoc/puredocparser.cpp
index d11ef3a3c7..644fe05438 100644
--- a/src/tools/qdoc/puredocparser.cpp
+++ b/src/tools/qdoc/puredocparser.cpp
@@ -118,9 +118,9 @@ void PureDocParser::parseSourceFile(const Location& location, const QString& fil
*/
bool PureDocParser::processQdocComments()
{
- QSet<QString> topicCommandsAllowed = topicCommands();
- QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
- QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
+ const QSet<QString>& topicCommandsAllowed = topicCommands();
+ const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
+ const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
while (tok != Tok_Eoi) {
if (tok == Tok_Doc) {
@@ -137,55 +137,68 @@ bool PureDocParser::processQdocComments()
/*
Doc parses the comment.
*/
- Doc doc(start_loc,end_loc,comment,metacommandsAllowed);
+ Doc doc(start_loc, end_loc, comment, metacommandsAllowed, topicCommandsAllowed);
QString topic;
- ArgList args;
+ bool isQmlPropertyTopic = false;
- QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
-
- /*
- There should be one topic command in the set,
- or none. If the set is empty, then the comment
- should be a function description.
- */
- if (topicCommandsUsed.count() > 0) {
- topic = *topicCommandsUsed.begin();
- args = doc.metaCommandArgs(topic);
+ const TopicList& topics = doc.topicsUsed();
+ if (!topics.isEmpty()) {
+ topic = topics[0].topic;
+ if ((topic == COMMAND_QMLPROPERTY) ||
+ (topic == COMMAND_QMLPROPERTYGROUP) ||
+ (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ isQmlPropertyTopic = true;
+ }
+ }
+ if (isQmlPropertyTopic && topics.size() > 1) {
+ qDebug() << "MULTIPLE TOPICS:" << doc.location().fileName() << doc.location().lineNo();
+ for (int i=0; i<topics.size(); ++i) {
+ qDebug() << " " << topics[i].topic << topics[i].args;
+ }
}
NodeList nodes;
- QList<Doc> docs;
+ DocList docs;
if (topic.isEmpty()) {
doc.location().warning(tr("This qdoc comment contains no topic command "
"(e.g., '\\%1', '\\%2').")
.arg(COMMAND_MODULE).arg(COMMAND_PAGE));
}
+ else if (isQmlPropertyTopic) {
+ Doc nodeDoc = doc;
+ processQmlProperties(nodeDoc, nodes, docs);
+ }
else {
- /*
- There is a topic command. Process it.
- */
- if ((topic == COMMAND_QMLPROPERTY) ||
- (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ ArgList args;
+ QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
+ if (topicCommandsUsed.count() > 0) {
+ topic = *topicCommandsUsed.begin();
+ args = doc.metaCommandArgs(topic);
+ }
+ if (topicCommandsUsed.count() > 1) {
+ QString topics;
+ QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
+ while (t != topicCommandsUsed.constEnd()) {
+ topics += " \\" + *t + ",";
+ ++t;
+ }
+ topics[topics.lastIndexOf(',')] = '.';
+ int i = topics.lastIndexOf(',');
+ topics[i] = ' ';
+ topics.insert(i+1,"and");
+ doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
+ }
+ ArgList::ConstIterator a = args.begin();
+ while (a != args.end()) {
Doc nodeDoc = doc;
- Node* node = processTopicCommandGroup(nodeDoc,topic,args);
+ Node* node = processTopicCommand(nodeDoc,topic,*a);
if (node != 0) {
nodes.append(node);
docs.append(nodeDoc);
}
- }
- else {
- ArgList::ConstIterator a = args.begin();
- while (a != args.end()) {
- Doc nodeDoc = doc;
- Node* node = processTopicCommand(nodeDoc,topic,*a);
- if (node != 0) {
- nodes.append(node);
- docs.append(nodeDoc);
- }
- ++a;
- }
+ ++a;
}
}
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp
index 7a3df4e4f2..a1e06c8020 100644
--- a/src/tools/qdoc/qdocdatabase.cpp
+++ b/src/tools/qdoc/qdocdatabase.cpp
@@ -612,7 +612,7 @@ void QDocDatabase::findAllObsoleteThings(const InnerNode* node)
case Node::QmlMethod:
if ((*c)->parent()) {
Node* parent = (*c)->parent();
- if (parent->subType() == Node::QmlPropertyGroup && parent->parent())
+ if (parent->type() == Node::QmlPropertyGroup && parent->parent())
parent = parent->parent();
if (parent && parent->subType() == Node::QmlClass && !parent->name().isEmpty())
name = parent->name() + "::" + name;
diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp
index 5f2ebdfd07..3283e978f4 100644
--- a/src/tools/qdoc/qdocindexfiles.cpp
+++ b/src/tools/qdoc/qdocindexfiles.cpp
@@ -133,7 +133,8 @@ void QDocIndexFiles::readIndexFile(const QString& path)
else {
// Use a fake directory, since we will copy the output to a sub directory of
// installDir when using "make install". This is just for a proper relative path.
- QDir installDir(path.section('/', 0, -3) + "/outputdir");
+ //QDir installDir(path.section('/', 0, -3) + "/outputdir");
+ QDir installDir(path.section('/', 0, -3) + '/' + Generator::outputSubdir());
indexUrl = installDir.relativeFilePath(path).section('/', 0, -2);
}
project_ = indexElement.attribute("project", QString());
@@ -217,8 +218,18 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
location = Location(name);
node = qbtn;
}
- else if (element.nodeName() == "qmlproperty") {
+ else if (element.nodeName() == "qmlpropertygroup") {
QmlClassNode* qcn = static_cast<QmlClassNode*>(parent);
+ QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name);
+ if (element.hasAttribute("location"))
+ name = element.attribute("location", QString());
+ if (!indexUrl.isEmpty())
+ location = Location(indexUrl + QLatin1Char('/') + name);
+ else if (!indexUrl.isNull())
+ location = Location(name);
+ node = qpgn;
+ }
+ else if (element.nodeName() == "qmlproperty") {
QString type = element.attribute("type");
bool attached = false;
if (element.attribute("attached") == "true")
@@ -226,7 +237,15 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
bool readonly = false;
if (element.attribute("writable") == "false")
readonly = true;
- QmlPropertyNode* qpn = new QmlPropertyNode(qcn, name, type, attached);
+ QmlPropertyNode* qpn = 0;
+ if (parent->type() == Node::Document) {
+ QmlClassNode* qcn = static_cast<QmlClassNode*>(parent);
+ qpn = new QmlPropertyNode(qcn, name, type, attached);
+ }
+ else if (parent->type() == Node::QmlPropertyGroup) {
+ QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(parent);
+ qpn = new QmlPropertyNode(qpgn, name, type, attached);
+ }
qpn->setReadOnly(readonly);
node = qpn;
}
@@ -281,10 +300,6 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
subtype = Node::QmlClass;
ptype = Node::ApiPage;
}
- else if (element.attribute("subtype") == "qmlpropertygroup") {
- subtype = Node::QmlPropertyGroup;
- ptype = Node::ApiPage;
- }
else if (element.attribute("subtype") == "qmlbasictype") {
subtype = Node::QmlBasicType;
ptype = Node::ApiPage;
@@ -501,7 +516,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
// Create some content for the node.
QSet<QString> emptySet;
- Doc doc(location, location, " ", emptySet); // placeholder
+ Doc doc(location, location, " ", emptySet, emptySet); // placeholder
node->setDoc(doc);
node->setIndexNodeFlag();
node->setOutputSubdirectory(project_.toLower());
@@ -644,6 +659,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
case Node::QmlProperty:
nodeName = "qmlproperty";
break;
+ case Node::QmlPropertyGroup:
+ nodeName = "qmlpropertygroup";
+ break;
case Node::QmlSignal:
nodeName = "qmlsignal";
break;
@@ -746,7 +764,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
QString fullName = node->fullDocumentName();
if (fullName != objName)
writer.writeAttribute("fullname", fullName);
- QString href = node->outputSubdirectory();
+ QString href;
+ if (Generator::useOutputSubdirs())
+ href = node->outputSubdirectory();
if (!href.isEmpty())
href.append(QLatin1Char('/'));
href.append(gen_->fullDocumentLocation(node));
@@ -927,6 +947,12 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("brief", brief);
}
break;
+ case Node::QmlPropertyGroup:
+ {
+ if (!brief.isEmpty())
+ writer.writeAttribute("brief", brief);
+ }
+ break;
case Node::Property:
{
const PropertyNode* propertyNode = static_cast<const PropertyNode*>(node);
@@ -1179,17 +1205,12 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
foreach (Node* child, cnodes) {
/*
- Don't generate anything for a QML property group node.
- It is just a place holder for a collection of QML property
- nodes. Recurse to its children, which are the QML property
- nodes.
-
- Do the same thing for collision nodes - we want children
- of collision nodes in the index, but leaving out the
- parent collision page will make searching for nodes easier.
+ Don't generate anything for a collision node. We want
+ children of collision nodes in the index, but leaving
+ out the parent collision page will make searching for
+ nodes easier.
*/
- if (child->subType() == Node::QmlPropertyGroup ||
- child->subType() == Node::Collision) {
+ if (child->subType() == Node::Collision) {
const InnerNode* pgn = static_cast<const InnerNode*>(child);
foreach (Node* c, pgn->childNodes()) {
generateIndexSections(writer, c, generateInternalNodes);
diff --git a/src/tools/qdoc/qdoctagfiles.cpp b/src/tools/qdoc/qdoctagfiles.cpp
index 1f6020fc09..a0054ea229 100644
--- a/src/tools/qdoc/qdoctagfiles.cpp
+++ b/src/tools/qdoc/qdoctagfiles.cpp
@@ -156,7 +156,7 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter& writer, const Inne
if (node->type() == Node::Class) {
writer.writeTextElement("name", node->fullDocumentName());
- writer.writeTextElement("filename", gen_->fullDocumentLocation(node,true));
+ writer.writeTextElement("filename", gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
// Classes contain information about their base classes.
const ClassNode* classNode = static_cast<const ClassNode*>(node);
@@ -175,7 +175,7 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter& writer, const Inne
}
else {
writer.writeTextElement("name", node->fullDocumentName());
- writer.writeTextElement("filename", gen_->fullDocumentLocation(node,true));
+ writer.writeTextElement("filename", gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
// Recurse to write all members.
generateTagFileMembers(writer, static_cast<const InnerNode*>(node));
@@ -291,7 +291,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const InnerN
writer.writeTextElement("type", "virtual " + functionNode->returnType());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node,true).split(QLatin1Char('#'));
+ QStringList pieces = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
@@ -332,7 +332,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const InnerN
const PropertyNode* propertyNode = static_cast<const PropertyNode*>(node);
writer.writeAttribute("type", propertyNode->dataType());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node,true).split(QLatin1Char('#'));
+ QStringList pieces = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
writer.writeTextElement("arglist", QString());
@@ -366,7 +366,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const InnerN
else
writer.writeAttribute("type", QString());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node,true).split(QLatin1Char('#'));
+ QStringList pieces = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
writer.writeTextElement("arglist", QString());
diff --git a/src/tools/qdoc/qmlcodeparser.cpp b/src/tools/qdoc/qmlcodeparser.cpp
index b9c0ad9218..28b9c3ec9b 100644
--- a/src/tools/qdoc/qmlcodeparser.cpp
+++ b/src/tools/qdoc/qmlcodeparser.cpp
@@ -70,6 +70,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_QMLTYPE Doc::alias("qmltype")
#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
+#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
#define COMMAND_QMLINHERITS Doc::alias("inherits")
#define COMMAND_QMLINSTANTIATES Doc::alias("instantiates")
@@ -166,9 +167,9 @@ void QmlCodeParser::parseSourceFile(const Location& location, const QString& fil
extractPragmas(newCode);
lexer->setCode(newCode, 1);
- QSet<QString> topicCommandsAllowed = topicCommands();
- QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
- QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
+ const QSet<QString>& topicCommandsAllowed = topicCommands();
+ const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
+ const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
if (parser->parse()) {
QQmlJS::AST::UiProgram *ast = parser->ast();
@@ -195,42 +196,52 @@ void QmlCodeParser::doneParsingSourceFiles()
{
}
+static QSet<QString> topicCommands_;
/*!
Returns the set of strings representing the topic commands.
*/
-QSet<QString> QmlCodeParser::topicCommands()
+const QSet<QString>& QmlCodeParser::topicCommands()
{
- return QSet<QString>() << COMMAND_VARIABLE
- << COMMAND_QMLCLASS
- << COMMAND_QMLTYPE
- << COMMAND_QMLPROPERTY
- << COMMAND_QMLATTACHEDPROPERTY
- << COMMAND_QMLSIGNAL
- << COMMAND_QMLATTACHEDSIGNAL
- << COMMAND_QMLMETHOD
- << COMMAND_QMLATTACHEDMETHOD
- << COMMAND_QMLBASICTYPE;
+ if (topicCommands_.isEmpty()) {
+ topicCommands_ << COMMAND_VARIABLE
+ << COMMAND_QMLCLASS
+ << COMMAND_QMLTYPE
+ << COMMAND_QMLPROPERTY
+ << COMMAND_QMLPROPERTYGROUP
+ << COMMAND_QMLATTACHEDPROPERTY
+ << COMMAND_QMLSIGNAL
+ << COMMAND_QMLATTACHEDSIGNAL
+ << COMMAND_QMLMETHOD
+ << COMMAND_QMLATTACHEDMETHOD
+ << COMMAND_QMLBASICTYPE;
+ }
+ return topicCommands_;
}
+static QSet<QString> otherMetaCommands_;
/*!
Returns the set of strings representing the common metacommands
plus some other metacommands.
*/
-QSet<QString> QmlCodeParser::otherMetaCommands()
+const QSet<QString>& QmlCodeParser::otherMetaCommands()
{
- return commonMetaCommands() << COMMAND_STARTPAGE
- << COMMAND_QMLINHERITS
- << COMMAND_QMLDEFAULT
- << COMMAND_QMLREADONLY
- << COMMAND_DEPRECATED
- << COMMAND_INGROUP
- << COMMAND_INTERNAL
- << COMMAND_OBSOLETE
- << COMMAND_PRELIMINARY
- << COMMAND_SINCE
- << COMMAND_QMLABSTRACT
- << COMMAND_INQMLMODULE
- << COMMAND_WRAPPER;
+ if (otherMetaCommands_.isEmpty()) {
+ otherMetaCommands_ = commonMetaCommands();
+ otherMetaCommands_ << COMMAND_STARTPAGE
+ << COMMAND_QMLINHERITS
+ << COMMAND_QMLDEFAULT
+ << COMMAND_QMLREADONLY
+ << COMMAND_DEPRECATED
+ << COMMAND_INGROUP
+ << COMMAND_INTERNAL
+ << COMMAND_OBSOLETE
+ << COMMAND_PRELIMINARY
+ << COMMAND_SINCE
+ << COMMAND_QMLABSTRACT
+ << COMMAND_INQMLMODULE
+ << COMMAND_WRAPPER;
+ }
+ return otherMetaCommands_;
}
/*!
diff --git a/src/tools/qdoc/qmlcodeparser.h b/src/tools/qdoc/qmlcodeparser.h
index 5bdcfbfbbf..71b4660fe7 100644
--- a/src/tools/qdoc/qmlcodeparser.h
+++ b/src/tools/qdoc/qmlcodeparser.h
@@ -79,8 +79,8 @@ public:
void extractPragmas(QString &script);
protected:
- virtual QSet<QString> topicCommands();
- virtual QSet<QString> otherMetaCommands();
+ const QSet<QString>& topicCommands();
+ const QSet<QString>& otherMetaCommands();
private:
QQmlJS::Engine engine;
diff --git a/src/tools/qdoc/qmlparser/qqmljs.g b/src/tools/qdoc/qmlparser/qqmljs.g
index ff4f54374b..7ba6859534 100644
--- a/src/tools/qdoc/qmlparser/qqmljs.g
+++ b/src/tools/qdoc/qmlparser/qqmljs.g
@@ -316,7 +316,7 @@ public:
inline DiagnosticMessage diagnosticMessage() const
{
foreach (const DiagnosticMessage &d, diagnostic_messages) {
- if (! d.kind == DiagnosticMessage::Warning)
+ if (d.kind != DiagnosticMessage::Warning)
return d;
}
diff --git a/src/tools/qdoc/qmlparser/qqmljsparser_p.h b/src/tools/qdoc/qmlparser/qqmljsparser_p.h
index 1b13690547..6edfd844d0 100644
--- a/src/tools/qdoc/qmlparser/qqmljsparser_p.h
+++ b/src/tools/qdoc/qmlparser/qqmljsparser_p.h
@@ -175,7 +175,7 @@ public:
inline DiagnosticMessage diagnosticMessage() const
{
foreach (const DiagnosticMessage &d, diagnostic_messages) {
- if (! d.kind == DiagnosticMessage::Warning)
+ if (d.kind != DiagnosticMessage::Warning)
return d;
}
diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp
index 86b86c8f34..c049857717 100644
--- a/src/tools/qdoc/qmlvisitor.cpp
+++ b/src/tools/qdoc/qmlvisitor.cpp
@@ -67,6 +67,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_QMLTYPE Doc::alias(QLatin1String("qmltype"))
#define COMMAND_QMLMODULE Doc::alias(QLatin1String("qmlmodule"))
#define COMMAND_QMLPROPERTY Doc::alias(QLatin1String("qmlproperty"))
+#define COMMAND_QMLPROPERTYGROUP Doc::alias(QLatin1String("qmlpropertygroup"))
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias(QLatin1String("qmlattachedproperty"))
#define COMMAND_QMLINHERITS Doc::alias(QLatin1String("inherits"))
#define COMMAND_QMLINSTANTIATES Doc::alias(QLatin1String("instantiates"))
@@ -85,17 +86,17 @@ QT_BEGIN_NAMESPACE
QmlDocVisitor::QmlDocVisitor(const QString &filePath,
const QString &code,
QQmlJS::Engine *engine,
- QSet<QString> &commands,
- QSet<QString> &topics)
+ const QSet<QString> &commands,
+ const QSet<QString> &topics)
: nestingLevel(0)
{
lastEndOffset = 0;
- this->filePath = filePath;
+ this->filePath_ = filePath;
this->name = QFileInfo(filePath).baseName();
document = code;
this->engine = engine;
- this->commands = commands;
- this->topics = topics;
+ this->commands_ = commands;
+ this->topics_ = topics;
current = QDocDatabase::qdocDB()->treeRoot();
}
@@ -141,13 +142,89 @@ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) cons
return QQmlJS::AST::SourceLocation();
}
+#if 0
+ ArgList args;
+ QSet<QString>::iterator i = metacommands.begin();
+ while (i != metacommands.end()) {
+ if (topics_.contains(*i)) {
+ topic = *i;
+ break;
+ }
+ ++i;
+ }
+ if (!topic.isEmpty()) {
+ args = doc.metaCommandArgs(topic);
+ if ((topic == COMMAND_QMLCLASS) || (topic == COMMAND_QMLTYPE)) {
+ // do nothing.
+ }
+ else if (topic == COMMAND_QMLPROPERTY) {
+ if (node->type() == Node::QmlProperty) {
+ QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
+ qpn->setReadOnly(0);
+ if (qpn->dataType() == "alias") {
+ QStringList part = args[0].first.split(QLatin1Char(' '));
+ qpn->setDataType(part[0]);
+ }
+ }
+ }
+ else if (topic == COMMAND_QMLPROPERTYGROUP) {
+ // zzz ?
+ }
+ else if (topic == COMMAND_QMLMODULE) {
+ }
+ else if (topic == COMMAND_QMLATTACHEDPROPERTY) {
+ if (node->type() == Node::QmlProperty) {
+ QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
+ qpn->setReadOnly(0);
+ }
+ }
+ else if (topic == COMMAND_QMLSIGNAL) {
+ }
+ else if (topic == COMMAND_QMLATTACHEDSIGNAL) {
+ }
+ else if (topic == COMMAND_QMLMETHOD) {
+ }
+ else if (topic == COMMAND_QMLATTACHEDMETHOD) {
+ }
+ else if (topic == COMMAND_QMLBASICTYPE) {
+ }
+ }
+
+ if (node->type() == Node::QmlProperty) {
+ QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
+ for (int i=0; i<topicsUsed.size(); ++i) {
+ if (topicsUsed.at(i).topic == "qmlproperty") {
+ /*
+ A \qmlproperty command would be used in a QML file
+ to document the underlying property for a property
+ alias.
+ */
+ QmlPropArgs qpa;
+ if (splitQmlPropertyArg(doc, topicsUsed.at(i).args, qpa)) {
+ QmlPropertyNode* n = parent->hasQmlPropertyNode(qpa.name_);
+ if (n == 0)
+ n = new QmlPropertyNode(qpn, qpa.name_, qpa.type_, false);
+ n->setLocation(doc.location());
+ n->setReadOnly(qpn->isReadOnly());
+ if (qpn->isDefault())
+ n->setDefault();
+ }
+ else
+ qDebug() << " FAILED TO PARSE QML PROPERTY:"
+ << topicsUsed.at(i).topic << topicsUsed.at(i).args;
+ }
+ }
+ }
+
+#endif
+
/*!
Finds the nearest unused qdoc comment above the QML entity
represented by the \a node and processes the qdoc commands
- in that comment. The proceesed documentation is stored in
+ in that comment. The processed documentation is stored in
the \a node.
- If a qdoc comment is found about \a location, true is returned.
+ If a qdoc comment is found for \a location, true is returned.
If a comment is not found there, false is returned.
*/
bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Node* node)
@@ -156,23 +233,66 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
if (loc.isValid()) {
QString source = document.mid(loc.offset, loc.length);
- Location start(filePath);
+ Location start(filePath_);
start.setLineNo(loc.startLine);
start.setColumnNo(loc.startColumn);
- Location finish(filePath);
+ Location finish(filePath_);
finish.setLineNo(loc.startLine);
finish.setColumnNo(loc.startColumn);
- Doc doc(start, finish, source.mid(1), commands, topics);
+ Doc doc(start, finish, source.mid(1), commands_, topics_);
+ const TopicList& topicsUsed = doc.topicsUsed();
+ NodeList nodes;
+ Node* nodePassedIn = node;
+ InnerNode* parent = nodePassedIn->parent();
node->setDoc(doc);
- applyMetacommands(loc, node, doc);
+ nodes.append(node);
+ if (topicsUsed.size() > 0) {
+ for (int i=0; i<topicsUsed.size(); ++i) {
+ if (topicsUsed.at(i).topic == QString("qmlpropertygroup")) {
+ qDebug() << "PROPERTY GROUP COMMAND SEEN:" << topicsUsed.at(i).args << filePath_;
+ break;
+ }
+ }
+ for (int i=0; i<topicsUsed.size(); ++i) {
+ QString topic = topicsUsed.at(i).topic;
+ QString args = topicsUsed.at(i).args;
+ if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ QmlPropArgs qpa;
+ if (splitQmlPropertyArg(doc, args, qpa)) {
+ if (qpa.name_ == nodePassedIn->name()) {
+ if (nodePassedIn->isAlias())
+ nodePassedIn->setDataType(qpa.type_);
+ }
+ else {
+ bool isAttached = (topic == COMMAND_QMLATTACHEDPROPERTY);
+ QmlPropertyNode* n = parent->hasQmlProperty(qpa.name_);
+ if (n == 0)
+ n = new QmlPropertyNode(parent, qpa.name_, qpa.type_, isAttached);
+ n->setLocation(doc.location());
+ n->setDoc(doc);
+ n->setReadOnly(nodePassedIn->isReadOnly());
+ if (nodePassedIn->isDefault())
+ n->setDefault();
+ if (isAttached)
+ n->setReadOnly(0);
+ nodes.append(n);
+ }
+ }
+ else
+ qDebug() << " FAILED TO PARSE QML PROPERTY:" << topic << args;
+ }
+ }
+ }
+ for (int i=0; i<nodes.size(); ++i)
+ applyMetacommands(loc, nodes.at(i), doc);
usedComments.insert(loc.offset);
if (doc.isEmpty()) {
return false;
}
return true;
}
- Location codeLoc(filePath);
+ Location codeLoc(filePath_);
codeLoc.setLineNo(location.startLine);
node->setLocation(codeLoc);
return false;
@@ -237,80 +357,13 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
Doc& doc)
{
QDocDatabase* qdb = QDocDatabase::qdocDB();
-
- const TopicList& topicsUsed = doc.topicsUsed();
- if (topicsUsed.size() > 0) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- for (int i=0; i<topicsUsed.size(); ++i) {
- if (topicsUsed.at(i).topic == "qmlproperty") {
- QmlPropArgs qpa;
- if (splitQmlPropertyArg(doc, topicsUsed.at(i).args, qpa)) {
- QmlPropertyNode* n = new QmlPropertyNode(qpn, qpa.name_, qpa.type_, false);
- n->setLocation(doc.location());
- qpn->appendQmlPropNode(n);
- n->setReadOnly(qpn->isReadOnly());
- if (qpn->isDefault())
- n->setDefault();
- }
- else
- qDebug() << " FAILED TO PARSE QML PROPERTY:"
- << topicsUsed.at(i).topic << topicsUsed.at(i).args;
- }
- }
- }
- }
QSet<QString> metacommands = doc.metaCommandsUsed();
if (metacommands.count() > 0) {
- QString topic;
- ArgList args;
+ metacommands.subtract(topics_);
QSet<QString>::iterator i = metacommands.begin();
while (i != metacommands.end()) {
- if (topics.contains(*i)) {
- topic = *i;
- break;
- }
- ++i;
- }
- if (!topic.isEmpty()) {
- args = doc.metaCommandArgs(topic);
- if ((topic == COMMAND_QMLCLASS) || (topic == COMMAND_QMLTYPE)) {
- // do nothing.
- }
- else if (topic == COMMAND_QMLPROPERTY) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- qpn->setReadOnly(0);
- if (qpn->dataType() == "alias") {
- QStringList part = args[0].first.split(QLatin1Char(' '));
- qpn->setDataType(part[0]);
- }
- }
- }
- else if (topic == COMMAND_QMLMODULE) {
- }
- else if (topic == COMMAND_QMLATTACHEDPROPERTY) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- qpn->setReadOnly(0);
- }
- }
- else if (topic == COMMAND_QMLSIGNAL) {
- }
- else if (topic == COMMAND_QMLATTACHEDSIGNAL) {
- }
- else if (topic == COMMAND_QMLMETHOD) {
- }
- else if (topic == COMMAND_QMLATTACHEDMETHOD) {
- }
- else if (topic == COMMAND_QMLBASICTYPE) {
- }
- }
- metacommands.subtract(topics);
- i = metacommands.begin();
- while (i != metacommands.end()) {
QString command = *i;
- args = doc.metaCommandArgs(command);
+ ArgList args = doc.metaCommandArgs(command);
if (command == COMMAND_QMLABSTRACT) {
if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
node->setAbstract(true);
@@ -528,7 +581,9 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
QmlClassNode *qmlClass = static_cast<QmlClassNode *>(current);
if (qmlClass) {
QString name = member->name.toString();
- QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlClass, name, type, false);
+ QmlPropertyNode* qmlPropNode = qmlClass->hasQmlProperty(name);
+ if (qmlPropNode == 0)
+ qmlPropNode = new QmlPropertyNode(qmlClass, name, type, false);
qmlPropNode->setReadOnly(member->isReadonlyMember);
if (member->isDefaultMember)
qmlPropNode->setDefault();
diff --git a/src/tools/qdoc/qmlvisitor.h b/src/tools/qdoc/qmlvisitor.h
index 2c3ff341d6..cdb7ae7391 100644
--- a/src/tools/qdoc/qmlvisitor.h
+++ b/src/tools/qdoc/qmlvisitor.h
@@ -45,7 +45,6 @@
#include <qstring.h>
#include "qqmljsastvisitor_p.h"
#include "node.h"
-#include "tree.h"
QT_BEGIN_NAMESPACE
@@ -72,8 +71,8 @@ public:
QmlDocVisitor(const QString &filePath,
const QString &code,
QQmlJS::Engine *engine,
- QSet<QString> &commands,
- QSet<QString> &topics);
+ const QSet<QString> &commands,
+ const QSet<QString> &topics);
virtual ~QmlDocVisitor();
bool visit(QQmlJS::AST::UiImportList *imports);
@@ -113,12 +112,12 @@ private:
QQmlJS::Engine *engine;
quint32 lastEndOffset;
quint32 nestingLevel;
- QString filePath;
+ QString filePath_;
QString name;
QString document;
ImportList importList;
- QSet<QString> commands;
- QSet<QString> topics;
+ QSet<QString> commands_;
+ QSet<QString> topics_;
QSet<quint32> usedComments;
InnerNode *current;
};
diff --git a/src/tools/qdoc/tokenizer.cpp b/src/tools/qdoc/tokenizer.cpp
index 224d451f4c..e1ca28eef8 100644
--- a/src/tools/qdoc/tokenizer.cpp
+++ b/src/tools/qdoc/tokenizer.cpp
@@ -237,7 +237,11 @@ int Tokenizer::getToken()
return getTokenAfterPreprocessor();
case '&':
yyCh = getChar();
- if (yyCh == '&' || yyCh == '=') {
+ /*
+ Removed check for '&&', only interpret '&=' as an operator.
+ '&&' is also used for an rvalue reference. QTBUG-32675
+ */
+ if (yyCh == '=') {
yyCh = getChar();
return Tok_SomeOperator;
}
diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp
index 553c569ae9..8c5ecdcfe9 100644
--- a/src/tools/qdoc/tree.cpp
+++ b/src/tools/qdoc/tree.cpp
@@ -169,7 +169,7 @@ const Node* Tree::findNode(const QStringList& path,
if (node && i == path.size()
&& (!(findFlags & NonFunction) || node->type() != Node::Function
|| ((FunctionNode*)node)->metaness() == FunctionNode::MacroWithoutParams)) {
- if ((node != self) && (node->subType() != Node::QmlPropertyGroup)) {
+ if ((node != self) && (node->type() != Node::QmlPropertyGroup)) {
if (node->subType() == Node::Collision) {
node = node->applyModuleIdentifier(start);
}
diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h
index e44b8d7d12..d569d8944b 100644
--- a/src/tools/qdoc/tree.h
+++ b/src/tools/qdoc/tree.h
@@ -128,7 +128,6 @@ class Tree
void addPropertyFunction(PropertyNode *property,
const QString &funcName,
PropertyNode::FunctionRole funcRole);
- void addToQmlModule(Node* node);
void resolveInheritance(NamespaceNode *rootNode = 0);
void resolveProperties();
void resolveCppToQmlLinks();
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
index 6b311a8e55..510a552c12 100644
--- a/src/tools/rcc/main.cpp
+++ b/src/tools/rcc/main.cpp
@@ -49,31 +49,12 @@
#include <qtextstream.h>
#include <qatomic.h>
#include <qglobal.h>
+#include <qcoreapplication.h>
+#include <qcommandlineoption.h>
+#include <qcommandlineparser.h>
-QT_BEGIN_NAMESPACE
-void showHelp(const QString &argv0, const QString &error)
-{
- fprintf(stderr, "Qt resource compiler\n");
- if (!error.isEmpty())
- fprintf(stderr, "%s: %s\n", qPrintable(argv0), qPrintable(error));
- fprintf(stderr, "Usage: %s [options] <inputs>\n\n"
- "Options:\n"
- " -o file write output to file rather than stdout\n"
- " -name name create an external initialization function with name\n"
- " -threshold level threshold to consider compressing files\n"
- " -compress level compress input files by level\n"
- " -root path prefix resource access path with root path\n"
- " -no-compress disable all compression\n"
- " -binary output a binary file for use as a dynamic resource\n"
- " -namespace turn off namespace macros\n"
- " -project Output a resource file containing all\n"
- " files from the current directory\n"
- " -list lists .qrc file entries\n"
- " -version display version\n"
- " -help display this information\n",
- qPrintable(argv0));
-}
+QT_BEGIN_NAMESPACE
void dumpRecursive(const QDir &dir, QTextStream &out)
{
@@ -127,92 +108,103 @@ int createProject(const QString &outFileName)
int runRcc(int argc, char *argv[])
{
- QString outFilename;
- bool helpRequested = false;
- bool list = false;
- bool projectRequested = false;
- QStringList filenamesIn;
+ QCoreApplication app(argc, argv);
+ QCoreApplication::setApplicationVersion(QString::fromLatin1(QT_VERSION_STR));
- QStringList args = qCmdLineArgs(argc, argv);
+ // Note that rcc isn't translated.
+ // If you use this code as an example for a translated app, make sure to translate the strings.
+ QCommandLineParser parser;
+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
+ parser.setApplicationDescription(QStringLiteral("Qt Resource Compiler version %1").arg(QString::fromLatin1(QT_VERSION_STR)));
+ parser.addHelpOption();
+ parser.addVersionOption();
+
+ QCommandLineOption outputOption(QStringList() << QStringLiteral("o") << QStringLiteral("output"));
+ outputOption.setDescription(QStringLiteral("Write output to <file> rather than stdout."));
+ outputOption.setValueName(QStringLiteral("file"));
+ parser.addOption(outputOption);
+
+ QCommandLineOption nameOption(QStringLiteral("name"), QStringLiteral("Create an external initialization function with <name>."), QStringLiteral("name"));
+ parser.addOption(nameOption);
+
+ QCommandLineOption rootOption(QStringLiteral("root"), QStringLiteral("Prefix resource access path with root path."), QStringLiteral("path"));
+ parser.addOption(rootOption);
+
+ QCommandLineOption compressOption(QStringLiteral("compress"), QStringLiteral("Compress input files by <level>."), QStringLiteral("level"));
+ parser.addOption(compressOption);
+
+ QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression."));
+ parser.addOption(nocompressOption);
+
+ QCommandLineOption thresholdOption(QStringLiteral("threshold"), QStringLiteral("Threshold to consider compressing files."), QStringLiteral("level"));
+ parser.addOption(thresholdOption);
+
+ QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
+ parser.addOption(binaryOption);
+
+ QCommandLineOption namespaceOption(QStringLiteral("namespace"), QStringLiteral("Turn off namespace macros."));
+ parser.addOption(namespaceOption);
+
+ QCommandLineOption verboseOption(QStringLiteral("verbose"), QStringLiteral("Enable verbose mode."));
+ parser.addOption(verboseOption);
+
+ QCommandLineOption listOption(QStringLiteral("list"), QStringLiteral("Only list .qrc file entries, do not generate code."));
+ parser.addOption(listOption);
+
+ QCommandLineOption projectOption(QStringLiteral("project"), QStringLiteral("Output a resource file containing all files from the current directory."));
+ parser.addOption(projectOption);
+
+ parser.addPositionalArgument(QStringLiteral("inputs"), QStringLiteral("Input files (*.qrc)."));
- RCCResourceLibrary library;
//parse options
+ parser.process(app);
+
QString errorMsg;
- for (int i = 1; i < args.count() && errorMsg.isEmpty(); i++) {
- if (args[i].isEmpty())
- continue;
- if (args[i][0] == QLatin1Char('-')) { // option
- QString opt = args[i];
- if (opt == QLatin1String("-o")) {
- if (!(i < argc-1)) {
- errorMsg = QLatin1String("Missing output name");
- break;
- }
- outFilename = args[++i];
- } else if (opt == QLatin1String("-name")) {
- if (!(i < argc-1)) {
- errorMsg = QLatin1String("Missing target name");
- break;
- }
- library.setInitName(args[++i]);
- } else if (opt == QLatin1String("-root")) {
- if (!(i < argc-1)) {
- errorMsg = QLatin1String("Missing root path");
- break;
- }
- library.setResourceRoot(QDir::cleanPath(args[++i]));
- if (library.resourceRoot().isEmpty()
- || library.resourceRoot().at(0) != QLatin1Char('/'))
- errorMsg = QLatin1String("Root must start with a /");
- } else if (opt == QLatin1String("-compress")) {
- if (!(i < argc-1)) {
- errorMsg = QLatin1String("Missing compression level");
- break;
- }
- library.setCompressLevel(args[++i].toInt());
- } else if (opt == QLatin1String("-threshold")) {
- if (!(i < argc-1)) {
- errorMsg = QLatin1String("Missing compression threshold");
- break;
- }
- library.setCompressThreshold(args[++i].toInt());
- } else if (opt == QLatin1String("-binary")) {
- library.setFormat(RCCResourceLibrary::Binary);
- } else if (opt == QLatin1String("-namespace")) {
- library.setUseNameSpace(!library.useNameSpace());
- } else if (opt == QLatin1String("-verbose")) {
- library.setVerbose(true);
- } else if (opt == QLatin1String("-list")) {
- list = true;
- } else if (opt == QLatin1String("-version") || opt == QLatin1String("-v")) {
- fprintf(stderr, "Qt Resource Compiler version %s\n", QT_VERSION_STR);
- return 1;
- } else if (opt == QLatin1String("-help") || opt == QLatin1String("-h")) {
- helpRequested = true;
- } else if (opt == QLatin1String("-no-compress")) {
- library.setCompressLevel(-2);
- } else if (opt == QLatin1String("-project")) {
- projectRequested = true;
- } else {
- errorMsg = QString::fromLatin1("Unknown option: '%1'").arg(args[i]);
- }
- } else {
- if (!QFile::exists(args[i])) {
- qWarning("%s: File does not exist '%s'",
- qPrintable(args[0]), qPrintable(args[i]));
- return 1;
- }
- filenamesIn.append(args[i]);
+ RCCResourceLibrary library;
+ QString outFilename = parser.value(outputOption);
+ if (parser.isSet(nameOption))
+ library.setInitName(parser.value(nameOption));
+ if (parser.isSet(rootOption)) {
+ library.setResourceRoot(QDir::cleanPath(parser.value(rootOption)));
+ if (library.resourceRoot().isEmpty()
+ || library.resourceRoot().at(0) != QLatin1Char('/'))
+ errorMsg = QLatin1String("Root must start with a /");
+ }
+ if (parser.isSet(compressOption))
+ library.setCompressLevel(parser.value(compressOption).toInt());
+ if (parser.isSet(nocompressOption))
+ library.setCompressLevel(-2);
+ if (parser.isSet(thresholdOption))
+ library.setCompressThreshold(parser.value(thresholdOption).toInt());
+ if (parser.isSet(binaryOption))
+ library.setFormat(RCCResourceLibrary::Binary);
+ if (parser.isSet(namespaceOption))
+ library.setUseNameSpace(!library.useNameSpace());
+ if (parser.isSet(verboseOption))
+ library.setVerbose(true);
+
+ const bool list = parser.isSet(listOption);
+ const bool projectRequested = parser.isSet(projectOption);
+ const QStringList filenamesIn = parser.positionalArguments();
+
+ foreach (const QString &file, filenamesIn) {
+ if (!QFile::exists(file)) {
+ qWarning("%s: File does not exist '%s'", argv[0], qPrintable(file));
+ return 1;
}
}
- if (projectRequested && !helpRequested) {
+ if (projectRequested) {
return createProject(outFilename);
}
- if (!filenamesIn.size() || !errorMsg.isEmpty() || helpRequested) {
- showHelp(args[0], errorMsg);
+ if (filenamesIn.isEmpty())
+ errorMsg = QStringLiteral("No input files specified.");
+
+ if (!errorMsg.isEmpty()) {
+ fprintf(stderr, "%s: %s\n", argv[0], qPrintable(errorMsg));
+ parser.showHelp(1);
return 1;
}
QFile errorDevice;
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 1d36647b6a..cd9fe2ac86 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -52,6 +52,8 @@
#include <qstack.h>
#include <qxmlstream.h>
+#include <algorithm>
+
// Note: A copy of this file is used in Qt Designer (qttools/src/designer/src/lib/shared/rcc.cpp)
QT_BEGIN_NAMESPACE
@@ -905,7 +907,7 @@ bool RCCResourceLibrary::writeDataStructure()
//sort by hash value for binary lookup
QList<RCCFileInfo*> m_children = file->m_children.values();
- qSort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
+ std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
//write out the actual data now
for (int i = 0; i < m_children.size(); ++i) {
@@ -924,7 +926,7 @@ bool RCCResourceLibrary::writeDataStructure()
//sort by hash value for binary lookup
QList<RCCFileInfo*> m_children = file->m_children.values();
- qSort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
+ std::sort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
//write out the actual data now
for (int i = 0; i < m_children.size(); ++i) {
diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp
index a9bbc237a6..c29292a99b 100644
--- a/src/tools/uic/main.cpp
+++ b/src/tools/uic/main.cpp
@@ -47,101 +47,75 @@
#include <qdir.h>
#include <qtextstream.h>
#include <qtextcodec.h>
+#include <qcoreapplication.h>
+#include <qcommandlineoption.h>
+#include <qcommandlineparser.h>
QT_BEGIN_NAMESPACE
-static const char *error = 0;
-
-void showHelp(const char *appName)
-{
- fprintf(stderr, "Qt User Interface Compiler version %s\n", QT_VERSION_STR);
- if (error)
- fprintf(stderr, "%s: %s\n", appName, error);
-
- fprintf(stderr, "Usage: %s [options] <uifile>\n\n"
- " -h, -help display this help and exit\n"
- " -v, -version display version\n"
- " -d, -dependencies display the dependencies\n"
- " -o <file> place the output into <file>\n"
- " -tr <func> use func() for i18n\n"
- " -p, -no-protection disable header protection\n"
- " -n, -no-implicit-includes disable generation of #include-directives\n"
- " for forms generated by uic3\n"
- " -g <name> change generator\n"
- "\n", appName);
-}
-
int runUic(int argc, char *argv[])
{
- Driver driver;
+ QCoreApplication app(argc, argv);
+ QCoreApplication::setApplicationVersion(QString::fromLatin1(QT_VERSION_STR));
- const char *fileName = 0;
-
- int arg = 1;
- while (arg < argc) {
- QString opt = QString::fromLocal8Bit(argv[arg]);
- if (opt == QLatin1String("-h") || opt == QLatin1String("-help")) {
- showHelp(argv[0]);
- return 0;
- } else if (opt == QLatin1String("-d") || opt == QLatin1String("-dependencies")) {
- driver.option().dependencies = true;
- } else if (opt == QLatin1String("-v") || opt == QLatin1String("-version")) {
- fprintf(stderr, "Qt User Interface Compiler version %s\n", QT_VERSION_STR);
- return 0;
- } else if (opt == QLatin1String("-o") || opt == QLatin1String("-output")) {
- ++arg;
- if (!argv[arg]) {
- showHelp(argv[0]);
- return 1;
- }
- driver.option().outputFile = QFile::decodeName(argv[arg]);
- } else if (opt == QLatin1String("-p") || opt == QLatin1String("-no-protection")) {
- driver.option().headerProtection = false;
- } else if (opt == QLatin1String("-n") || opt == QLatin1String("-no-implicit-includes")) {
- driver.option().implicitIncludes = false;
- } else if (opt == QLatin1String("-postfix")) {
- ++arg;
- if (!argv[arg]) {
- showHelp(argv[0]);
- return 1;
- }
- driver.option().postfix = QLatin1String(argv[arg]);
- } else if (opt == QLatin1String("-3")) {
- ++arg;
- if (!argv[arg]) {
- showHelp(argv[0]);
- return 1;
- }
- driver.option().uic3 = QFile::decodeName(argv[arg]);
- } else if (opt == QLatin1String("-tr") || opt == QLatin1String("-translate")) {
- ++arg;
- if (!argv[arg]) {
- showHelp(argv[0]);
- return 1;
- }
- driver.option().translateFunction = QLatin1String(argv[arg]);
- } else if (opt == QLatin1String("-g") || opt == QLatin1String("-generator")) {
- ++arg;
- if (!argv[arg]) {
- showHelp(argv[0]);
- return 1;
- }
- QString name = QString::fromLocal8Bit(argv[arg]).toLower ();
- driver.option().generator = (name == QLatin1String ("java")) ? Option::JavaGenerator : Option::CppGenerator;
- } else if (!fileName) {
- fileName = argv[arg];
- } else {
- showHelp(argv[0]);
- return 1;
- }
+ Driver driver;
- ++arg;
- }
+ // Note that uic isn't translated.
+ // If you use this code as an example for a translated app, make sure to translate the strings.
+ QCommandLineParser parser;
+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
+ parser.setApplicationDescription(QStringLiteral("Qt User Interface Compiler version %1").arg(QString::fromLatin1(QT_VERSION_STR)));
+ parser.addHelpOption();
+ parser.addVersionOption();
+
+ QCommandLineOption dependenciesOption(QStringList() << QStringLiteral("d") << QStringLiteral("dependencies"));
+ dependenciesOption.setDescription(QStringLiteral("Display the dependencies."));
+ parser.addOption(dependenciesOption);
+
+ QCommandLineOption outputOption(QStringList() << QStringLiteral("o") << QStringLiteral("output"));
+ outputOption.setDescription(QStringLiteral("Place the output into <file>"));
+ outputOption.setValueName(QStringLiteral("file"));
+ parser.addOption(outputOption);
+
+ QCommandLineOption noProtOption(QStringList() << QStringLiteral("p") << QStringLiteral("no-protection"));
+ noProtOption.setDescription(QStringLiteral("Disable header protection."));
+ parser.addOption(noProtOption);
+
+ QCommandLineOption noImplicitIncludesOption(QStringList() << QStringLiteral("n") << QStringLiteral("no-implicit-includes"));
+ noImplicitIncludesOption.setDescription(QStringLiteral("Disable generation of #include-directives."));
+ parser.addOption(noImplicitIncludesOption);
+
+ QCommandLineOption postfixOption(QStringLiteral("postfix"));
+ postfixOption.setDescription(QStringLiteral("Postfix to add to all generated classnames."));
+ postfixOption.setValueName(QStringLiteral("postfix"));
+ parser.addOption(postfixOption);
+
+ QCommandLineOption translateOption(QStringList() << QStringLiteral("tr") << QStringLiteral("translate"));
+ translateOption.setDescription(QStringLiteral("Use <function> for i18n."));
+ translateOption.setValueName(QStringLiteral("function"));
+ parser.addOption(translateOption);
+
+ QCommandLineOption generatorOption(QStringList() << QStringLiteral("g") << QStringLiteral("generator"));
+ generatorOption.setDescription(QStringLiteral("Select generator."));
+ generatorOption.setValueName(QStringLiteral("java|cpp"));
+ parser.addOption(generatorOption);
+
+ parser.addPositionalArgument(QStringLiteral("[uifile]"), QStringLiteral("Input file (*.ui), otherwise stdin."));
+
+ parser.process(app);
+
+ driver.option().dependencies = parser.isSet(dependenciesOption);
+ driver.option().outputFile = parser.value(outputOption);
+ driver.option().headerProtection = !parser.isSet(noProtOption);
+ driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption);
+ driver.option().postfix = parser.value(postfixOption);
+ driver.option().translateFunction = parser.value(translateOption);
+ driver.option().generator = (parser.value(generatorOption).toLower() == QLatin1String("java")) ? Option::JavaGenerator : Option::CppGenerator;
QString inputFile;
- if (fileName)
- inputFile = QString::fromLocal8Bit(fileName);
- else
+ if (!parser.positionalArguments().isEmpty())
+ inputFile = parser.positionalArguments().first();
+ else // reading from stdin
driver.option().headerProtection = false;
if (driver.option().dependencies) {
diff --git a/src/tools/uic/option.h b/src/tools/uic/option.h
index 141eb4806a..14ed422d63 100644
--- a/src/tools/uic/option.h
+++ b/src/tools/uic/option.h
@@ -73,7 +73,6 @@ struct Option
QString prefix;
QString postfix;
QString translateFunction;
- QString uic3;
#ifdef QT_UIC_JAVA_GENERATOR
QString javaPackage;
QString javaOutputDirectory;
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index c08a034d9e..82f70f323b 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -63,6 +63,8 @@
#include "qmimedata.h"
#include "qspinbox.h"
#include "qdialogbuttonbox.h"
+#include "qscreen.h"
+#include "qcursor.h"
QT_BEGIN_NAMESPACE
@@ -920,6 +922,8 @@ signals:
private slots:
void rgbEd();
void hsvEd();
+ void htmlEd();
+
private:
void showCurrentColor();
int hue, sat, val;
@@ -931,6 +935,7 @@ private:
QLabel *lblRed;
QLabel *lblGreen;
QLabel *lblBlue;
+ QLabel *lblHtml;
QColSpinBox *hEd;
QColSpinBox *sEd;
QColSpinBox *vEd;
@@ -939,6 +944,7 @@ private:
QColSpinBox *bEd;
QColSpinBox *alphaEd;
QLabel *alphaLab;
+ QLineEdit *htEd;
QColorShowLabel *lab;
bool rgbOriginal;
QColorDialog *colorDialog;
@@ -1230,6 +1236,19 @@ QColorShower::QColorShower(QColorDialog *parent)
#endif
alphaEd->hide();
alphaLab->hide();
+ lblHtml = new QLabel(this);
+ htEd = new QLineEdit(this);
+#ifndef QT_NO_SHORTCUT
+ lblHtml->setBuddy(htEd);
+#endif
+
+ QRegularExpression regExp(QStringLiteral("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
+ QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
+ htEd->setValidator(validator);
+
+ lblHtml->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ gl->addWidget(lblHtml, 5, 1);
+ gl->addWidget(htEd, 5, 2);
connect(hEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
connect(sEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
@@ -1239,6 +1258,7 @@ QColorShower::QColorShower(QColorDialog *parent)
connect(gEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
connect(bEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
connect(alphaEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
+ connect(htEd, SIGNAL(textEdited(QString)), this, SLOT(htmlEd()));
retranslateStrings();
}
@@ -1251,7 +1271,7 @@ inline bool QColorDialogPrivate::isAlphaVisible() const { return cs->isAlphaVisi
QColor QColorDialogPrivate::currentQColor() const
{
- if (!options->testOption(QColorDialogOptions::DontUseNativeDialog) && nativeDialogInUse)
+ if (nativeDialogInUse)
return platformColorDialogHelper()->currentColor();
return cs->currentQColor();
}
@@ -1273,6 +1293,8 @@ void QColorShower::rgbEd()
sEd->setValue(sat);
vEd->setValue(val);
+ htEd->setText(QColor(curCol).name());
+
showCurrentColor();
emit newCol(currentColor());
updateQColor();
@@ -1293,6 +1315,31 @@ void QColorShower::hsvEd()
gEd->setValue(qGreen(currentColor()));
bEd->setValue(qBlue(currentColor()));
+ htEd->setText(c.name());
+
+ showCurrentColor();
+ emit newCol(currentColor());
+ updateQColor();
+}
+
+void QColorShower::htmlEd()
+{
+ QColor c;
+ QString t = htEd->text();
+ c.setNamedColor(t);
+ if (!c.isValid())
+ return;
+ curCol = qRgba(c.red(), c.green(), c.blue(), currentAlpha());
+ rgb2hsv(curCol, hue, sat, val);
+
+ hEd->setValue(hue);
+ sEd->setValue(sat);
+ vEd->setValue(val);
+
+ rEd->setValue(qRed(currentColor()));
+ gEd->setValue(qGreen(currentColor()));
+ bEd->setValue(qBlue(currentColor()));
+
showCurrentColor();
emit newCol(currentColor());
updateQColor();
@@ -1313,6 +1360,8 @@ void QColorShower::setRgb(QRgb rgb)
gEd->setValue(qGreen(currentColor()));
bEd->setValue(qBlue(currentColor()));
+ htEd->setText(QColor(rgb).name());
+
showCurrentColor();
updateQColor();
}
@@ -1336,6 +1385,8 @@ void QColorShower::setHsv(int h, int s, int v)
gEd->setValue(qGreen(currentColor()));
bEd->setValue(qBlue(currentColor()));
+ htEd->setText(c.name());
+
showCurrentColor();
updateQColor();
}
@@ -1349,6 +1400,7 @@ void QColorShower::retranslateStrings()
lblGreen->setText(QColorDialog::tr("&Green:"));
lblBlue->setText(QColorDialog::tr("Bl&ue:"));
alphaLab->setText(QColorDialog::tr("A&lpha channel:"));
+ lblHtml->setText(QColorDialog::tr("&HTML:"));
}
void QColorShower::updateQColor()
@@ -1362,16 +1414,20 @@ void QColorShower::updateQColor()
//sets all widgets to display h,s,v
void QColorDialogPrivate::_q_newHsv(int h, int s, int v)
{
- cs->setHsv(h, s, v);
- cp->setCol(h, s);
- lp->setCol(h, s, v);
+ if (!nativeDialogInUse) {
+ cs->setHsv(h, s, v);
+ cp->setCol(h, s);
+ lp->setCol(h, s, v);
+ }
}
//sets all widgets to display rgb
void QColorDialogPrivate::setCurrentColor(QRgb rgb)
{
- cs->setRgb(rgb);
- _q_newColorTypedIn(rgb);
+ if (!nativeDialogInUse) {
+ cs->setRgb(rgb);
+ _q_newColorTypedIn(rgb);
+ }
}
// hack; doesn't keep curCol in sync, so use with care
@@ -1421,13 +1477,24 @@ bool QColorDialogPrivate::selectColor(const QColor &col)
return false;
}
+QColor QColorDialogPrivate::grabScreenColor(const QPoint &p)
+{
+ const QDesktopWidget *desktop = QApplication::desktop();
+ const QPixmap pixmap = QGuiApplication::screens().at(desktop->screenNumber())->grabWindow(desktop->winId(),
+ p.x(), p.y(), 1, 1);
+ QImage i = pixmap.toImage();
+ return i.pixel(0, 0);
+}
+
//sets all widgets except cs to display rgb
void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
{
- int h, s, v;
- rgb2hsv(rgb, h, s, v);
- cp->setCol(h, s);
- lp->setCol(h, s, v);
+ if (!nativeDialogInUse) {
+ int h, s, v;
+ rgb2hsv(rgb, h, s, v);
+ cp->setCol(h, s);
+ lp->setCol(h, s, v);
+ }
}
void QColorDialogPrivate::_q_nextCustom(int r, int c)
@@ -1450,6 +1517,52 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
custom->setSelected(-1,-1);
}
+void QColorDialogPrivate::_q_pickScreenColor()
+{
+ Q_Q(QColorDialog);
+ screenColorPicking = true;
+ // If user pushes Escape, the last color before picking will be restored.
+ beforeScreenColorPicking = cs->currentColor();
+ /*For some reason, q->grabMouse(Qt::CrossCursor) doesn't change
+ * the cursor, and therefore I have to change it manually.
+ */
+ q->grabMouse();
+#ifndef QT_NO_CURSOR
+ q->setCursor(Qt::CrossCursor);
+#endif
+ q->grabKeyboard();
+ /* With setMouseTracking(true) the desired color can be more precisedly picked up,
+ * and continuously pushing the mouse button is not necessary.
+ */
+ q->setMouseTracking(true);
+
+ addCusBt->setDisabled(true);
+ buttons->setDisabled(true);
+ screenColorPickerButton->setDisabled(true);
+
+ q->setCurrentColor(grabScreenColor(QCursor::pos()));
+ lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
+ .arg(QCursor::pos().x())
+ .arg(QCursor::pos().y())
+ .arg(q->currentColor().name()));
+}
+
+void QColorDialogPrivate::releaseColorPicking()
+{
+ Q_Q(QColorDialog);
+ screenColorPicking = false;
+ q->releaseMouse();
+ q->releaseKeyboard();
+#ifndef QT_NO_CURSOR
+ q->setCursor(Qt::ArrowCursor);
+#endif
+ q->setMouseTracking(false);
+ lblScreenColorInfo->setText(QLatin1String("\n"));
+ addCusBt->setDisabled(false);
+ buttons->setDisabled(false);
+ screenColorPickerButton->setDisabled(false);
+}
+
void QColorDialogPrivate::init(const QColor &initial)
{
Q_Q(QColorDialog);
@@ -1457,9 +1570,24 @@ void QColorDialogPrivate::init(const QColor &initial)
q->setSizeGripEnabled(false);
q->setWindowTitle(QColorDialog::tr("Select Color"));
+ // default: use the native dialog if possible. Can be overridden in setOptions()
nativeDialogInUse = (platformColorDialogHelper() != 0);
-
+ screenColorPicking = false;
nextCust = 0;
+
+ if (!nativeDialogInUse)
+ initWidgets();
+
+#ifdef Q_WS_MAC
+ delegate = 0;
+#endif
+
+ q->setCurrentColor(initial);
+}
+
+void QColorDialogPrivate::initWidgets()
+{
+ Q_Q(QColorDialog);
QVBoxLayout *mainLay = new QVBoxLayout(q);
// there's nothing in this dialog that benefits from sizing up
mainLay->setSizeConstraint(QLayout::SetFixedSize);
@@ -1494,6 +1622,15 @@ void QColorDialogPrivate::init(const QColor &initial)
leftLay->addWidget(lblBasicColors);
leftLay->addWidget(standard);
+#if !defined(Q_OS_WINCE) && !defined(QT_SMALL_COLORDIALOG)
+ // The screen color picker button
+ screenColorPickerButton = new QPushButton(QColorDialog::tr("Pick Screen Color"));
+ leftLay->addWidget(screenColorPickerButton);
+ lblScreenColorInfo = new QLabel(QLatin1String("\n"));
+ leftLay->addWidget(lblScreenColorInfo);
+ q->connect(screenColorPickerButton, SIGNAL(clicked()), SLOT(_q_pickScreenColor()));
+#endif
+
#if !defined(Q_OS_WINCE)
leftLay->addStretch();
#endif
@@ -1597,12 +1734,6 @@ void QColorDialogPrivate::init(const QColor &initial)
QObject::connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
retranslateStrings();
-
-#ifdef Q_WS_MAC
- delegate = 0;
-#endif
-
- q->setCurrentColor(initial);
}
void QColorDialogPrivate::initHelper(QPlatformDialogHelper *h)
@@ -1667,6 +1798,11 @@ static const Qt::WindowFlags DefaultWindowFlags =
during the execution of the program. Use setCustomColor() to set
the custom colors, and use customColor() to get them.
+ When pressing the "Pick Screen Color" button, the cursor changes to a haircross
+ and the colors on the screen are scanned. The user can pick up one by clicking
+ the mouse or the Enter button. Pressing Escape restores the last color selected
+ before entering this mode.
+
The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
how to use QColorDialog as well as other built-in Qt dialogs.
@@ -1708,12 +1844,13 @@ QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
void QColorDialog::setCurrentColor(const QColor &color)
{
Q_D(QColorDialog);
- d->setCurrentColor(color.rgb());
- d->selectColor(color);
- d->setCurrentAlpha(color.alpha());
-
- if (!testOption(QColorDialog::DontUseNativeDialog) && d->nativeDialogInUse)
+ if (d->nativeDialogInUse)
d->platformColorDialogHelper()->setCurrentColor(color);
+ else {
+ d->setCurrentColor(color.rgb());
+ d->selectColor(color);
+ d->setCurrentAlpha(color.alpha());
+ }
}
QColor QColorDialog::currentColor() const
@@ -1783,10 +1920,14 @@ void QColorDialog::setOptions(ColorDialogOptions options)
return;
d->options->setOptions(QColorDialogOptions::ColorDialogOptions(int(options)));
- d->buttons->setVisible(!(options & NoButtons));
- d->showAlpha(options & ShowAlphaChannel);
- if (options & DontUseNativeDialog)
+ if ((options & DontUseNativeDialog) && d->nativeDialogInUse) {
d->nativeDialogInUse = false;
+ d->initWidgets();
+ }
+ if (!d->nativeDialogInUse) {
+ d->buttons->setVisible(!(options & NoButtons));
+ d->showAlpha(options & ShowAlphaChannel);
+ }
}
QColorDialog::ColorDialogOptions QColorDialog::options() const
@@ -1868,7 +2009,7 @@ void QColorDialog::setVisible(bool visible)
}
#else
- if (!(options() & DontUseNativeDialog) && d->nativeDialogInUse) {
+ if (d->nativeDialogInUse) {
d->setNativeDialogVisible(visible);
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
// updates the state correctly, but skips showing the non-native version:
@@ -1983,6 +2124,57 @@ void QColorDialog::changeEvent(QEvent *e)
}
/*!
+ \reimp
+*/
+void QColorDialog::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ setCurrentColor(d->grabScreenColor(e->globalPos()));
+ d->lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
+ .arg(e->globalPos().x())
+ .arg(e->globalPos().y())
+ .arg(currentColor().name()));
+ return;
+ }
+ QDialog::mouseMoveEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QColorDialog::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ setCurrentColor(d->grabScreenColor(e->globalPos()));
+ d->releaseColorPicking();
+ return;
+ }
+ QDialog::mouseReleaseEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QColorDialog::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ if (e->key() == Qt::Key_Escape) {
+ d->releaseColorPicking();
+ d->setCurrentColor(d->beforeScreenColorPicking);
+ } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
+ setCurrentColor(d->grabScreenColor(QCursor::pos()));
+ d->releaseColorPicking();
+ }
+ e->accept();
+ return;
+ }
+ QDialog::keyPressEvent(e);
+}
+
+/*!
Closes the dialog and sets its result code to \a result. If this dialog
is shown with exec(), done() causes the local event loop to finish,
and exec() to return \a result.
diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h
index f6dc627a05..c7a1d6f400 100644
--- a/src/widgets/dialogs/qcolordialog.h
+++ b/src/widgets/dialogs/qcolordialog.h
@@ -112,6 +112,9 @@ Q_SIGNALS:
protected:
void changeEvent(QEvent *event);
+ virtual void mouseMoveEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void keyPressEvent(QKeyEvent *);
void done(int result);
private:
@@ -123,6 +126,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_nextCustom(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_pickScreenColor())
friend class QColorShower;
};
diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index 695e95d26c..08199cc7c1 100644
--- a/src/widgets/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
@@ -82,11 +82,13 @@ public:
{ return static_cast<QPlatformColorDialogHelper *>(platformHelper()); }
void init(const QColor &initial);
+ void initWidgets();
QRgb currentColor() const;
QColor currentQColor() const;
void setCurrentColor(QRgb rgb);
void setCurrentQColor(const QColor &color);
bool selectColor(const QColor &color);
+ QColor grabScreenColor(const QPoint &p);
int currentAlpha() const;
void setCurrentAlpha(int a);
@@ -101,6 +103,8 @@ public:
void _q_nextCustom(int, int);
void _q_newCustom(int, int);
void _q_newStandard(int, int);
+ void _q_pickScreenColor();
+ void releaseColorPicking();
QWellArray *custom;
QWellArray *standard;
@@ -112,12 +116,16 @@ public:
QColorShower *cs;
QLabel *lblBasicColors;
QLabel *lblCustomColors;
+ QLabel *lblScreenColorInfo;
QPushButton *ok;
QPushButton *cancel;
QPushButton *addCusBt;
+ QPushButton *screenColorPickerButton;
QColor selectedQColor;
int nextCust;
bool smallDisplay;
+ bool screenColorPicking;
+ QRgb beforeScreenColorPicking;
QSharedPointer<QColorDialogOptions> options;
QPointer<QObject> receiverToDisconnectOnClose;
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index 2cda99a269..e1097dd1bb 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -767,8 +767,10 @@ void QDialog::setVisible(bool visible)
if (d->eventLoop)
d->eventLoop->exit();
}
+
+ const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
if (d->mainDef && isActiveWindow()
- && d->styleHint(QPlatformDialogHelper::SnapToDefaultButton).toBool())
+ && theme->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool())
QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center()));
}
diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h
index eb0cb2372b..5064efa35d 100644
--- a/src/widgets/dialogs/qdialog_p.h
+++ b/src/widgets/dialogs/qdialog_p.h
@@ -111,7 +111,7 @@ public:
QPointer<QEventLoop> eventLoop;
- bool nativeDialogInUse; // Assigned in setVisible_sys() in derived classes.
+ bool nativeDialogInUse;
QPlatformDialogHelper *platformHelper() const;
private:
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index c42752311f..62cec34b2b 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -57,6 +57,7 @@
#include <stdlib.h>
#include <qsettings.h>
#include <qdebug.h>
+#include <qmimedatabase.h>
#include <qapplication.h>
#include <qstylepainter.h>
#if !defined(Q_OS_WINCE)
@@ -86,15 +87,27 @@ Q_GLOBAL_STATIC(QString, lastVisitedDir)
typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook = 0;
+typedef QUrl (*_qt_filedialog_existing_directory_url_hook)(QWidget *parent, const QString &caption, const QUrl &dir, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_url_hook qt_filedialog_existing_directory_url_hook = 0;
+
typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook = 0;
+typedef QUrl (*_qt_filedialog_open_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_open_file_url_hook qt_filedialog_open_file_url_hook = 0;
+
typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook = 0;
+typedef QList<QUrl> (*_qt_filedialog_open_file_urls_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_open_file_urls_hook qt_filedialog_open_file_urls_hook = 0;
+
typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook = 0;
+typedef QUrl (*_qt_filedialog_save_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_save_file_url_hook qt_filedialog_save_file_url_hook = 0;
+
/*!
\class QFileDialog
\brief The QFileDialog class provides a dialog that allow users to select files or directories.
@@ -243,6 +256,11 @@ Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_h
static functions will always be an application modal dialog. If
you want to use sheets, use QFileDialog::open() instead.
+ \value DontUseCustomDirectoryIcons Always use the default directory icon.
+ Some platforms allow the user to set a different icon. Custom icon lookup
+ cause a big performance impact over network or removable drives.
+ Setting this will enable the QFileIconProvider::DontUseCustomDirectoryIcons
+ option in the icon provider. This enum value was added in Qt 5.2.
*/
/*!
@@ -258,37 +276,76 @@ Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_h
/*!
\fn void QFileDialog::filesSelected(const QStringList &selected)
- When the selection changes and the dialog is accepted, this signal is
- emitted with the (possibly empty) list of \a selected files.
+ When the selection changes for local operations and the dialog is
+ accepted, this signal is emitted with the (possibly empty) list
+ of \a selected files.
\sa currentChanged(), QDialog::Accepted
*/
+/*!
+ \fn void QFileDialog::urlsSelected(const QList<QUrl> &urls)
+
+ When the selection changes and the dialog is accepted, this signal is
+ emitted with the (possibly empty) list of selected \a urls.
+
+ \sa currentUrlChanged(), QDialog::Accepted
+ \since 5.2
+*/
/*!
\fn void QFileDialog::fileSelected(const QString &file)
- When the selection changes and the dialog is accepted, this signal is
- emitted with the (possibly empty) selected \a file.
+ When the selection changes for local operations and the dialog is
+ accepted, this signal is emitted with the (possibly empty)
+ selected \a file.
\sa currentChanged(), QDialog::Accepted
*/
+/*!
+ \fn void QFileDialog::urlSelected(const QUrl &url)
+
+ When the selection changes and the dialog is accepted, this signal is
+ emitted with the (possibly empty) selected \a url.
+
+ \sa currentUrlChanged(), QDialog::Accepted
+ \since 5.2
+*/
/*!
\fn void QFileDialog::currentChanged(const QString &path)
- When the current file changes, this signal is emitted with the
- new file name as the \a path parameter.
+ When the current file changes for local operations, this signal is
+ emitted with the new file name as the \a path parameter.
\sa filesSelected()
*/
/*!
+ \fn void QFileDialog::currentUrlChanged(const QUrl &url)
+
+ When the current file changes, this signal is emitted with the
+ new file URL as the \a url parameter.
+
+ \sa urlsSelected()
+ \since 5.2
+*/
+
+/*!
\fn void QFileDialog::directoryEntered(const QString &directory)
\since 4.3
+ This signal is emitted for local operations when the user enters
+ a \a directory.
+*/
+
+/*!
+ \fn void QFileDialog::directoryUrlEntered(const QUrl &directory)
+
This signal is emitted when the user enters a \a directory.
+
+ \since 5.2
*/
/*!
@@ -532,11 +589,10 @@ QFileDialogPrivate::~QFileDialogPrivate()
void QFileDialogPrivate::initHelper(QPlatformDialogHelper *h)
{
QFileDialog *d = q_func();
- QObject::connect(h, SIGNAL(fileSelected(QString)), d, SIGNAL(fileSelected(QString)));
- QObject::connect(h, SIGNAL(filesSelected(QStringList)), d, SIGNAL(filesSelected(QStringList)));
- QObject::connect(h, SIGNAL(currentChanged(QString)), d, SIGNAL(currentChanged(QString)));
- QObject::connect(h, SIGNAL(directoryEntered(QString)), d, SIGNAL(directoryEntered(QString)));
- QObject::connect(h, SIGNAL(directoryEntered(QString)), d, SLOT(_q_nativeEnterDirectory(QString)));
+ QObject::connect(h, SIGNAL(fileSelected(QUrl)), d, SLOT(_q_nativeFileSelected(QUrl)));
+ QObject::connect(h, SIGNAL(filesSelected(QList<QUrl>)), d, SLOT(_q_nativeFilesSelected(QList<QUrl>)));
+ QObject::connect(h, SIGNAL(currentChanged(QUrl)), d, SLOT(_q_nativeCurrentChanged(QUrl)));
+ QObject::connect(h, SIGNAL(directoryEntered(QUrl)), d, SLOT(_q_nativeEnterDirectory(QUrl)));
QObject::connect(h, SIGNAL(filterSelected(QString)), d, SIGNAL(filterSelected(QString)));
static_cast<QPlatformFileDialogHelper *>(h)->setOptions(options);
}
@@ -550,8 +606,8 @@ void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
options->setSidebarUrls(qFileDialogUi->sidebar->urls());
const QDir directory = q->directory();
options->setInitialDirectory(directory.exists() ?
- directory.absolutePath() :
- QString());
+ QUrl::fromLocalFile(directory.absolutePath()) :
+ QUrl());
options->setInitiallySelectedNameFilter(q->selectedNameFilter());
options->setInitiallySelectedFiles(userSelectedFiles());
}
@@ -742,6 +798,15 @@ void QFileDialog::setOptions(Options options)
if (changed & ShowDirsOnly)
setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files);
+
+ if (changed & DontUseCustomDirectoryIcons) {
+ QFileIconProvider::Options providerOptions = iconProvider()->options();
+ if (options & DontUseCustomDirectoryIcons)
+ providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons;
+ else
+ providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons;
+ iconProvider()->setOptions(providerOptions);
+ }
}
QFileDialog::Options QFileDialog::options() const
@@ -850,7 +915,7 @@ void QFileDialog::setDirectory(const QString &directory)
d->setLastVisitedDirectory(newDirectory);
if (d->nativeDialogInUse){
- d->setDirectory_sys(newDirectory);
+ d->setDirectory_sys(QUrl::fromLocalFile(newDirectory));
return;
}
if (d->rootPath() == newDirectory)
@@ -875,7 +940,42 @@ void QFileDialog::setDirectory(const QString &directory)
QDir QFileDialog::directory() const
{
Q_D(const QFileDialog);
- return QDir(d->nativeDialogInUse ? d->directory_sys() : d->rootPath());
+ return QDir(d->nativeDialogInUse ? d->directory_sys().toLocalFile() : d->rootPath());
+}
+
+/*!
+ Sets the file dialog's current \a directory url.
+
+ \note The non-native QFileDialog supports only local files.
+
+ \since 5.2
+*/
+void QFileDialog::setDirectoryUrl(const QUrl &directory)
+{
+ Q_D(QFileDialog);
+ if (!directory.isValid())
+ return;
+
+ if (d->nativeDialogInUse)
+ d->setDirectory_sys(directory);
+ else if (directory.isLocalFile())
+ setDirectory(directory.toLocalFile());
+ else
+ qWarning() << "Non-native QFileDialog supports only local files";
+}
+
+/*!
+ Returns the url of the directory currently being displayed in the dialog.
+
+ \since 5.2
+*/
+QUrl QFileDialog::directoryUrl() const
+{
+ Q_D(const QFileDialog);
+ if (d->nativeDialogInUse)
+ return d->directory_sys();
+ else
+ return QUrl::fromLocalFile(directory().absolutePath());
}
/*!
@@ -890,7 +990,7 @@ void QFileDialog::selectFile(const QString &filename)
return;
if (d->nativeDialogInUse){
- d->selectFile_sys(filename);
+ d->selectFile_sys(QUrl::fromLocalFile(filename));
return;
}
@@ -927,6 +1027,28 @@ void QFileDialog::selectFile(const QString &filename)
d->lineEdit()->setText(file);
}
+/*!
+ Selects the given \a url in the file dialog.
+
+ \note The non-native QFileDialog supports only local files.
+
+ \sa selectedUrls()
+ \since 5.2
+*/
+void QFileDialog::selectUrl(const QUrl &url)
+{
+ Q_D(QFileDialog);
+ if (!url.isValid())
+ return;
+
+ if (d->nativeDialogInUse)
+ d->selectFile_sys(url);
+ else if (url.isLocalFile())
+ selectFile(url.toLocalFile());
+ else
+ qWarning() << "Non-native QFileDialog supports only local files";
+}
+
#ifdef Q_OS_UNIX
Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0)
{
@@ -1015,17 +1137,19 @@ QStringList QFileDialogPrivate::typedFiles() const
// Return selected files without defaulting to the root of the file system model
// used for initializing QFileDialogOptions for native dialogs. The default is
// not suitable for native dialogs since it mostly equals directory().
-QStringList QFileDialogPrivate::userSelectedFiles() const
+QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
{
+ QList<QUrl> files;
+
if (nativeDialogInUse)
- return addDefaultSuffixToFiles(selectedFiles_sys());
+ return addDefaultSuffixToUrls(selectedFiles_sys());
- QStringList files;
foreach (const QModelIndex &index, qFileDialogUi->listView->selectionModel()->selectedRows())
- files.append(index.data(QFileSystemModel::FilePathRole).toString());
+ files.append(QUrl::fromLocalFile(index.data(QFileSystemModel::FilePathRole).toString()));
if (files.isEmpty() && !lineEdit()->text().isEmpty())
- files = typedFiles();
+ foreach (const QString &path, typedFiles())
+ files.append(QUrl::fromLocalFile(path));
return files;
}
@@ -1056,6 +1180,20 @@ QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesT
return files;
}
+QList<QUrl> QFileDialogPrivate::addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const
+{
+ QList<QUrl> urls;
+ for (int i=0; i<urlsToFix.size(); ++i) {
+ QUrl url = urlsToFix.at(i);
+ // if the filename has no suffix, add the default suffix
+ const QString defaultSuffix = options->defaultSuffix();
+ if (!defaultSuffix.isEmpty() && !url.path().endsWith(QLatin1Char('/')) && url.path().lastIndexOf(QLatin1Char('.')) == -1)
+ url.setPath(url.path() + QLatin1Char('.') + defaultSuffix);
+ urls.append(url);
+ }
+ return urls;
+}
+
/*!
Returns a list of strings containing the absolute paths of the
@@ -1068,7 +1206,9 @@ QStringList QFileDialog::selectedFiles() const
{
Q_D(const QFileDialog);
- QStringList files = d->userSelectedFiles();
+ QStringList files;
+ foreach (const QUrl &file, d->userSelectedFiles())
+ files.append(file.toLocalFile());
if (files.isEmpty()) {
const FileMode fm = fileMode();
if (fm != ExistingFile && fm != ExistingFiles)
@@ -1077,6 +1217,27 @@ QStringList QFileDialog::selectedFiles() const
return files;
}
+/*!
+ Returns a list of urls containing the selected files in the dialog.
+ If no files are selected, or the mode is not ExistingFiles or
+ ExistingFile, selectedUrls() contains the current path in the viewport.
+
+ \sa selectedNameFilter(), selectUrl()
+ \since 5.2
+*/
+QList<QUrl> QFileDialog::selectedUrls() const
+{
+ Q_D(const QFileDialog);
+ if (d->nativeDialogInUse) {
+ return d->userSelectedFiles();
+ } else {
+ QList<QUrl> urls;
+ foreach (const QString &file, selectedFiles())
+ urls.append(QUrl::fromLocalFile(file));
+ return urls;
+ }
+}
+
/*
Makes a list of filters from ;;-separated text.
Used by the mac and windows implementations
@@ -1281,6 +1442,75 @@ void QFileDialog::setFilter(QDir::Filters filters)
d->showHiddenAction->setChecked((filters & QDir::Hidden));
}
+static QString nameFilterForMime(const QString &mimeType)
+{
+ QMimeDatabase db;
+ QMimeType mime(db.mimeTypeForName(mimeType));
+ if (mime.isValid()) {
+ if (mime.isDefault()) {
+ return QFileDialog::tr("All files (*)");
+ } else {
+ const QString patterns = mime.globPatterns().join(QLatin1Char(' '));
+ return mime.comment() + QStringLiteral(" (") + patterns + QLatin1Char(')');
+ }
+ }
+ return QString();
+}
+
+/*!
+ \since 5.2
+
+ Sets the \a filters used in the file dialog, from a list of MIME types.
+
+ Convenience method for setNameFilters().
+ Uses QMimeType to create a name filter from the glob patterns and description
+ defined in each MIME type.
+
+ Use application/octet-stream for the "All files (*)" filter, since that
+ is the base MIME type for all files.
+
+ Calling setMimeTypeFilters overrides any previously set name filters,
+ and changes the return value of nameFilters().
+
+ \snippet code/src_gui_dialogs_qfiledialog.cpp 13
+*/
+void QFileDialog::setMimeTypeFilters(const QStringList &filters)
+{
+ Q_D(QFileDialog);
+ QStringList nameFilters;
+ foreach (const QString &mimeType, filters) {
+ const QString text = nameFilterForMime(mimeType);
+ if (!text.isEmpty())
+ nameFilters.append(text);
+ }
+ setNameFilters(nameFilters);
+ d->options->setMimeTypeFilters(filters);
+}
+
+/*!
+ \since 5.2
+
+ Returns the MIME type filters that are in operation on this file
+ dialog.
+*/
+QStringList QFileDialog::mimeTypeFilters() const
+{
+ return d_func()->options->mimeTypeFilters();
+}
+
+/*!
+ \since 5.2
+
+ Sets the current MIME type \a filter.
+
+*/
+void QFileDialog::selectMimeTypeFilter(const QString &filter)
+{
+ const QString text = nameFilterForMime(filter);
+ if (!text.isEmpty())
+ selectNameFilter(text);
+}
+
/*!
\property QFileDialog::viewMode
\brief the way files and directories are displayed in the dialog
@@ -1526,6 +1756,8 @@ bool QFileDialog::confirmOverwrite() const
filename if it has no suffix already. The suffix is typically
used to indicate the file type (e.g. "txt" indicates a text
file).
+
+ If the first character is a dot ('.'), it is removed.
*/
void QFileDialog::setDefaultSuffix(const QString &suffix)
{
@@ -1798,6 +2030,48 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
}
/*!
+ This is a convenience static function that returns an existing file
+ selected by the user. If the user presses Cancel, it returns an
+ empty url.
+
+ The function is used similarly to QFileDialog::getOpenFileName(). In
+ particular \a parent, \a caption, \a dir, \a filter, \a selectedFilter
+ and \a options are used in the exact same way.
+
+ The main difference with QFileDialog::getOpenFileName() comes from
+ the ability offered to the user to select a remote file. That's why
+ the return type and the type of \a dir is QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to fetch the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getOpenFileName(), getOpenFileUrls(), getSaveFileUrl(), getExistingDirectoryUrl()
+ \since 5.2
+*/
+QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_open_file_url_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_open_file_url_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+
+ // Falls back to local file
+ return QUrl::fromLocalFile(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+}
+
+/*!
This is a convenience static function that will return one or more existing
files selected by the user.
@@ -1883,6 +2157,55 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
}
/*!
+ This is a convenience static function that will return or or more existing
+ files selected by the user. If the user presses Cancel, it returns an
+ empty list.
+
+ The function is used similarly to QFileDialog::getOpenFileNames(). In
+ particular \a parent, \a caption, \a dir, \a filter, \a selectedFilter
+ and \a options are used in the exact same way.
+
+ The main difference with QFileDialog::getOpenFileNames() comes from
+ the ability offered to the user to select remote files. That's why
+ the return type and the type of \a dir are respectively QList<QUrl>
+ and QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to fetch the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getOpenFileNames(), getOpenFileUrl(), getSaveFileUrl(), getExistingDirectoryUrl()
+ \since 5.2
+*/
+QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_open_file_urls_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_open_file_urls_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+
+ // Falls back to local files
+ QList<QUrl> urls;
+
+ const QStringList fileNames = getOpenFileNames(parent, caption, dir.toLocalFile(), filter, selectedFilter, options);
+ foreach (const QString &fileName, fileNames)
+ urls << QUrl::fromLocalFile(fileName);
+
+ return urls;
+}
+
+/*!
This is a convenience static function that will return a file name selected
by the user. The file does not have to exist.
@@ -1971,6 +2294,48 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
}
/*!
+ This is a convenience static function that returns a file selected by
+ the user. The file does not have to exist. If the user presses Cancel,
+ it returns an empty url.
+
+ The function is used similarly to QFileDialog::getSaveFileName(). In
+ particular \a parent, \a caption, \a dir, \a filter, \a selectedFilter
+ and \a options are used in the exact same way.
+
+ The main difference with QFileDialog::getSaveFileName() comes from
+ the ability offered to the user to select a remote file. That's why
+ the return type and the type of \a dir is QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to save the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getSaveFileName(), getOpenFileUrl(), getOpenFileUrls(), getExistingDirectoryUrl()
+ \since 5.2
+*/
+QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_save_file_url_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_save_file_url_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+
+ // Falls back to local file
+ return QUrl::fromLocalFile(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+}
+
+/*!
This is a convenience static function that will return an existing
directory selected by the user.
@@ -2041,6 +2406,46 @@ QString QFileDialog::getExistingDirectory(QWidget *parent,
return QString();
}
+/*!
+ This is a convenience static function that will return an existing
+ directory selected by the user. If the user presses Cancel, it
+ returns an empty url.
+
+ The function is used similarly to QFileDialog::getExistingDirectory().
+ In particular \a parent, \a caption, \a dir and \a options are used
+ in the exact same way.
+
+ The main difference with QFileDialog::getExistingDirectory() comes from
+ the ability offered to the user to select a remote directory. That's why
+ the return type and the type of \a dir is QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to fetch the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getExistingDirectory(), getOpenFileUrl(), getOpenFileUrls(), getSaveFileUrl()
+ \since 5.2
+*/
+QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_existing_directory_url_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_existing_directory_url_hook(parent, caption, dir, options, supportedSchemes);
+
+ // Falls back to local file
+ return QUrl::fromLocalFile(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
+}
+
inline static QString _qt_get_directory(const QString &path)
{
QFileInfo info = QFileInfo(QDir::current(), path);
@@ -3119,10 +3524,42 @@ void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString oldNa
}
}
-void QFileDialogPrivate::_q_nativeEnterDirectory(const QString &directory)
+void QFileDialogPrivate::_q_nativeFileSelected(const QUrl &file)
+{
+ Q_Q(QFileDialog);
+ emit q->urlSelected(file);
+ if (file.isLocalFile())
+ emit q->fileSelected(file.toLocalFile());
+}
+
+void QFileDialogPrivate::_q_nativeFilesSelected(const QList<QUrl> &files)
+{
+ Q_Q(QFileDialog);
+ emit q->urlsSelected(files);
+ QStringList localFiles;
+ foreach (const QUrl &file, files)
+ if (file.isLocalFile())
+ localFiles.append(file.toLocalFile());
+ if (!localFiles.isEmpty())
+ emit q->filesSelected(localFiles);
+}
+
+void QFileDialogPrivate::_q_nativeCurrentChanged(const QUrl &file)
{
- if (!directory.isEmpty()) // Windows native dialogs occasionally emit signals with empty strings.
- *lastVisitedDir() = directory;
+ Q_Q(QFileDialog);
+ emit q->currentUrlChanged(file);
+ if (file.isLocalFile())
+ emit q->currentChanged(file.toLocalFile());
+}
+
+void QFileDialogPrivate::_q_nativeEnterDirectory(const QUrl &directory)
+{
+ Q_Q(QFileDialog);
+ emit q->directoryUrlEntered(directory);
+ if (!directory.isEmpty() && directory.isLocalFile()) { // Windows native dialogs occasionally emit signals with empty strings.
+ *lastVisitedDir() = directory.toLocalFile();
+ emit q->directoryEntered(directory.toLocalFile());
+ }
}
/*!
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index 98d1fd5695..404e16cde1 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -44,6 +44,7 @@
#include <QtCore/qdir.h>
#include <QtCore/qstring.h>
+#include <QtCore/qurl.h>
#include <QtWidgets/qdialog.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +59,6 @@ class QFileIconProvider;
class QFileDialogPrivate;
class QAbstractItemDelegate;
class QAbstractProxyModel;
-class QUrl;
class Q_WIDGETS_EXPORT QFileDialog : public QDialog
{
@@ -84,13 +84,14 @@ public:
enum Option
{
- ShowDirsOnly = 0x00000001,
- DontResolveSymlinks = 0x00000002,
- DontConfirmOverwrite = 0x00000004,
- DontUseSheet = 0x00000008,
- DontUseNativeDialog = 0x00000010,
- ReadOnly = 0x00000020,
- HideNameFilterDetails = 0x00000040
+ ShowDirsOnly = 0x00000001,
+ DontResolveSymlinks = 0x00000002,
+ DontConfirmOverwrite = 0x00000004,
+ DontUseSheet = 0x00000008,
+ DontUseNativeDialog = 0x00000010,
+ ReadOnly = 0x00000020,
+ HideNameFilterDetails = 0x00000040,
+ DontUseCustomDirectoryIcons = 0x00000080
};
Q_DECLARE_FLAGS(Options, Option)
@@ -105,9 +106,15 @@ public:
inline void setDirectory(const QDir &directory);
QDir directory() const;
+ void setDirectoryUrl(const QUrl &directory);
+ QUrl directoryUrl() const;
+
void selectFile(const QString &filename);
QStringList selectedFiles() const;
+ void selectUrl(const QUrl &url);
+ QList<QUrl> selectedUrls() const;
+
void setNameFilterDetailsVisible(bool enabled);
bool isNameFilterDetailsVisible() const;
@@ -117,6 +124,10 @@ public:
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
+ void setMimeTypeFilters(const QStringList &filters);
+ QStringList mimeTypeFilters() const;
+ void selectMimeTypeFilter(const QString &filter);
+
QDir::Filters filter() const;
void setFilter(QDir::Filters filters);
@@ -184,6 +195,12 @@ Q_SIGNALS:
void filesSelected(const QStringList &files);
void currentChanged(const QString &path);
void directoryEntered(const QString &directory);
+
+ void urlSelected(const QUrl &url);
+ void urlsSelected(const QList<QUrl> &urls);
+ void currentUrlChanged(const QUrl &url);
+ void directoryUrlEntered(const QUrl &directory);
+
void filterSelected(const QString &filter);
public:
@@ -195,6 +212,14 @@ public:
QString *selectedFilter = 0,
Options options = 0);
+ static QUrl getOpenFileUrl(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0,
+ const QStringList &supportedSchemes = QStringList());
+
static QString getSaveFileName(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
@@ -202,11 +227,25 @@ public:
QString *selectedFilter = 0,
Options options = 0);
+ static QUrl getSaveFileUrl(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0,
+ const QStringList &supportedSchemes = QStringList());
+
static QString getExistingDirectory(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
Options options = ShowDirsOnly);
+ static QUrl getExistingDirectoryUrl(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ Options options = ShowDirsOnly,
+ const QStringList &supportedSchemes = QStringList());
+
static QStringList getOpenFileNames(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
@@ -214,6 +253,14 @@ public:
QString *selectedFilter = 0,
Options options = 0);
+ static QList<QUrl> getOpenFileUrls(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0,
+ const QStringList &supportedSchemes = QStringList());
+
protected:
QFileDialog(const QFileDialogArgs &args);
@@ -240,7 +287,10 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_updateOkButton())
Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex &index))
Q_PRIVATE_SLOT(d_func(), void _q_enterDirectory(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_nativeEnterDirectory(const QString&))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeFileSelected(const QUrl &))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeFilesSelected(const QList<QUrl> &))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeCurrentChanged(const QUrl &))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeEnterDirectory(const QUrl&))
Q_PRIVATE_SLOT(d_func(), void _q_goToDirectory(const QString &path))
Q_PRIVATE_SLOT(d_func(), void _q_useNameFilter(int index))
Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index f8f33eb18d..e5a558bb91 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -130,8 +130,9 @@ public:
static QString workingDirectory(const QString &path);
static QString initialSelection(const QString &path);
QStringList typedFiles() const;
- QStringList userSelectedFiles() const;
+ QList<QUrl> userSelectedFiles() const;
QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const;
+ QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
bool removeDirectory(const QString &path);
void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text);
inline void updateFileNameLabel();
@@ -206,7 +207,10 @@ public:
void _q_updateOkButton();
void _q_currentChanged(const QModelIndex &index);
void _q_enterDirectory(const QModelIndex &index);
- void _q_nativeEnterDirectory(const QString &directory);
+ void _q_nativeFileSelected(const QUrl &file);
+ void _q_nativeFilesSelected(const QList<QUrl> &files);
+ void _q_nativeCurrentChanged(const QUrl &file);
+ void _q_nativeEnterDirectory(const QUrl &directory);
void _q_goToDirectory(const QString &);
void _q_useNameFilter(int index);
void _q_selectionChanged();
@@ -246,10 +250,10 @@ public:
// used instead.
bool canBeNativeDialog();
- void setDirectory_sys(const QString &directory);
- QString directory_sys() const;
- void selectFile_sys(const QString &filename);
- QStringList selectedFiles_sys() const;
+ void setDirectory_sys(const QUrl &directory);
+ QUrl directory_sys() const;
+ void selectFile_sys(const QUrl &filename);
+ QList<QUrl> selectedFiles_sys() const;
void setFilter_sys();
void selectNameFilter_sys(const QString &filter);
QString selectedNameFilter_sys() const;
@@ -346,30 +350,40 @@ inline QString QFileDialogPrivate::rootPath() const {
return model->rootPath();
}
-inline void QFileDialogPrivate::setDirectory_sys(const QString &directory)
+inline void QFileDialogPrivate::setDirectory_sys(const QUrl &directory)
{
- if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
+ QPlatformFileDialogHelper *helper = platformFileDialogHelper();
+
+ if (!helper)
+ return;
+
+ if (helper->isSupportedUrl(directory))
helper->setDirectory(directory);
}
-inline QString QFileDialogPrivate::directory_sys() const
+inline QUrl QFileDialogPrivate::directory_sys() const
{
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
return helper->directory();
return QString();
}
-inline void QFileDialogPrivate::selectFile_sys(const QString &filename)
+inline void QFileDialogPrivate::selectFile_sys(const QUrl &filename)
{
- if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
+ QPlatformFileDialogHelper *helper = platformFileDialogHelper();
+
+ if (!helper)
+ return;
+
+ if (helper->isSupportedUrl(filename))
helper->selectFile(filename);
}
-inline QStringList QFileDialogPrivate::selectedFiles_sys() const
+inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
{
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
return helper->selectedFiles();
- return QStringList();
+ return QList<QUrl>();
}
inline void QFileDialogPrivate::setFilter_sys()
diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index 213aefe5f5..0f12c2b80e 100644
--- a/src/widgets/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
@@ -238,7 +238,7 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
#endif
#ifdef Q_OS_WIN
- if (m_resolveSymlinks && fileInfo.isSymLink()) {
+ if (m_resolveSymlinks && info.isSymLink(/* ignoreNtfsSymLinks = */ true)) {
QFileInfo resolvedInfo(fileInfo.symLinkTarget());
resolvedInfo = resolvedInfo.canonicalFilePath();
if (resolvedInfo.exists()) {
diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h
index 0c4e644e40..447ee78edc 100644
--- a/src/widgets/dialogs/qfileinfogatherer_p.h
+++ b/src/widgets/dialogs/qfileinfogatherer_p.h
@@ -108,7 +108,13 @@ public:
return QExtendedInformation::System;
}
- bool isSymLink() const {
+ bool isSymLink(bool ignoreNtfsSymLinks = false) const
+ {
+ if (ignoreNtfsSymLinks) {
+#ifdef Q_OS_WIN
+ return !mFileInfo.suffix().compare(QLatin1String("lnk"), Qt::CaseInsensitive);
+#endif
+ }
return mFileInfo.isSymLink();
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 8e3ecc3e0e..81fa40f0e7 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -800,7 +800,7 @@ QString QFileSystemModelPrivate::name(const QModelIndex &index) const
if (!index.isValid())
return QString();
QFileSystemNode *dirNode = node(index);
- if (fileInfoGatherer.resolveSymlinks() && !resolvedSymLinks.isEmpty() && dirNode->isSymLink()) {
+ if (fileInfoGatherer.resolveSymlinks() && !resolvedSymLinks.isEmpty() && dirNode->isSymLink(/* ignoreNtfsSymLinks = */ true)) {
QString fullPath = QDir::fromNativeSeparators(filePath(index));
if (resolvedSymLinks.contains(fullPath))
return resolvedSymLinks[fullPath];
@@ -1669,7 +1669,7 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
return;
QStringList toRemove;
QStringList newFiles = files;
- qSort(newFiles.begin(), newFiles.end());
+ std::sort(newFiles.begin(), newFiles.end());
QHash<QString, QFileSystemNode*>::const_iterator i = parentNode->children.constBegin();
while (i != parentNode->children.constEnd()) {
QStringList::iterator iterator;
@@ -1874,7 +1874,7 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QL
}
// bundle up all of the changed signals into as few as possible.
- qSort(rowsToUpdate.begin(), rowsToUpdate.end());
+ std::sort(rowsToUpdate.begin(), rowsToUpdate.end());
QString min;
QString max;
for (int i = 0; i < rowsToUpdate.count(); ++i) {
diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h
index d61936d545..663be3d933 100644
--- a/src/widgets/dialogs/qfilesystemmodel_p.h
+++ b/src/widgets/dialogs/qfilesystemmodel_p.h
@@ -116,7 +116,7 @@ public:
inline bool isFile() const { if (info) return info->isFile(); return true; }
inline bool isSystem() const { if (info) return info->isSystem(); return true; }
inline bool isHidden() const { if (info) return info->isHidden(); return false; }
- inline bool isSymLink() const { if (info) return info->isSymLink(); return false; }
+ inline bool isSymLink(bool ignoreNtfsSymLinks = false) const { return info && info->isSymLink(ignoreNtfsSymLinks); }
inline bool caseSensitive() const { if (info) return info->isCaseSensitive(); return false; }
inline QIcon icon() const { if (info) return info->icon; return QIcon(); }
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
index 313b475f1f..b989ea7c86 100644
--- a/src/widgets/dialogs/qfontdialog.cpp
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -479,7 +479,22 @@ void QFontDialogPrivate::updateFamilies()
enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 };
- QStringList familyNames = fdb.families(writingSystem);
+ const QFontDialog::FontDialogOptions scalableMask = (QFontDialog::ScalableFonts | QFontDialog::NonScalableFonts);
+ const QFontDialog::FontDialogOptions spacingMask = (QFontDialog::ProportionalFonts | QFontDialog::MonospacedFonts);
+ const QFontDialog::FontDialogOptions options = q->options();
+
+ QStringList familyNames;
+ foreach (const QString &family, fdb.families(writingSystem)) {
+ if ((options & scalableMask) && (options & scalableMask) != scalableMask) {
+ if (bool(options & QFontDialog::ScalableFonts) != fdb.isSmoothlyScalable(family))
+ continue;
+ }
+ if ((options & spacingMask) && (options & spacingMask) != spacingMask) {
+ if (bool(options & QFontDialog::MonospacedFonts) != fdb.isFixedPitch(family))
+ continue;
+ }
+ familyNames << family;
+ }
familyList->model()->setStringList(familyNames);
@@ -837,10 +852,21 @@ QFont QFontDialog::selectedFont() const
This enum specifies various options that affect the look and feel
of a font dialog.
+ For instance, it allows to specify which type of font should be
+ displayed. If none are specified all fonts available will be listed.
+
+ Note that the font filtering options might not be supported on some
+ platforms (e.g. Mac). They are always supported by the non native
+ dialog (used on Windows or Linux).
+
\value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons. (Useful for "live dialogs".)
\value DontUseNativeDialog Use Qt's standard font dialog on the Mac instead of Apple's
native font panel. (Currently, the native dialog is never used,
but this is likely to change in future Qt releases.)
+ \value ScalableFonts Show scalable fonts
+ \value NonScalableFonts Show non scalable fonts
+ \value MonospacedFonts Show monospaced fonts
+ \value ProportionalFonts Show proportional fonts
\sa options, setOption(), testOption()
*/
diff --git a/src/widgets/dialogs/qfontdialog.h b/src/widgets/dialogs/qfontdialog.h
index c2d930bc1e..9956987cfe 100644
--- a/src/widgets/dialogs/qfontdialog.h
+++ b/src/widgets/dialogs/qfontdialog.h
@@ -64,7 +64,11 @@ class Q_WIDGETS_EXPORT QFontDialog : public QDialog
public:
enum FontDialogOption {
NoButtons = 0x00000001,
- DontUseNativeDialog = 0x00000002
+ DontUseNativeDialog = 0x00000002,
+ ScalableFonts = 0x00000004,
+ NonScalableFonts = 0x00000008,
+ MonospacedFonts = 0x00000010,
+ ProportionalFonts = 0x00000020
};
Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp
index 45aa49d552..c1f8deb4eb 100644
--- a/src/widgets/dialogs/qinputdialog.cpp
+++ b/src/widgets/dialogs/qinputdialog.cpp
@@ -49,6 +49,7 @@
#include "qlabel.h"
#include "qlayout.h"
#include "qlineedit.h"
+#include "qplaintextedit.h"
#include "qlistwidget.h"
#include "qpushbutton.h"
#include "qspinbox.h"
@@ -167,6 +168,7 @@ public:
void ensureLayout();
void ensureLineEdit();
+ void ensurePlainTextEdit();
void ensureComboBox();
void ensureListView();
void ensureIntSpinBox();
@@ -180,11 +182,13 @@ public:
void ensureLayout() const { const_cast<QInputDialogPrivate *>(this)->ensureLayout(); }
bool useComboBoxOrListView() const { return comboBox && comboBox->count() > 0; }
void _q_textChanged(const QString &text);
+ void _q_plainTextEditTextChanged();
void _q_currentRowChanged(const QModelIndex &newIndex, const QModelIndex &oldIndex);
mutable QLabel *label;
mutable QDialogButtonBox *buttonBox;
mutable QLineEdit *lineEdit;
+ mutable QPlainTextEdit *plainTextEdit;
mutable QSpinBox *intSpinBox;
mutable QDoubleSpinBox *doubleSpinBox;
mutable QComboBox *comboBox;
@@ -198,8 +202,8 @@ public:
};
QInputDialogPrivate::QInputDialogPrivate()
- : label(0), buttonBox(0), lineEdit(0), intSpinBox(0), doubleSpinBox(0), comboBox(0), listView(0),
- inputWidget(0), mainLayout(0)
+ : label(0), buttonBox(0), lineEdit(0), plainTextEdit(0), intSpinBox(0), doubleSpinBox(0),
+ comboBox(0), listView(0), inputWidget(0), mainLayout(0)
{
}
@@ -250,6 +254,21 @@ void QInputDialogPrivate::ensureLineEdit()
}
}
+void QInputDialogPrivate::ensurePlainTextEdit()
+{
+ Q_Q(QInputDialog);
+ if (!plainTextEdit) {
+ plainTextEdit = new QPlainTextEdit(q);
+ plainTextEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
+#ifndef QT_NO_IM
+ qt_widget_private(plainTextEdit)->inheritsInputMethodHints = 1;
+#endif
+ plainTextEdit->hide();
+ QObject::connect(plainTextEdit, SIGNAL(textChanged()),
+ q, SLOT(_q_plainTextEditTextChanged()));
+ }
+}
+
void QInputDialogPrivate::ensureComboBox()
{
Q_Q(QInputDialog);
@@ -344,6 +363,8 @@ void QInputDialogPrivate::setInputWidget(QWidget *widget)
// textValue
if (widget == lineEdit) {
lineEdit->setText(textValue);
+ } else if (widget == plainTextEdit) {
+ plainTextEdit->setPlainText(textValue);
} else if (widget == comboBox) {
setComboBoxText(textValue);
} else if (widget == listView) {
@@ -364,6 +385,9 @@ void QInputDialogPrivate::chooseRightTextInputWidget()
} else {
widget = comboBox;
}
+ } else if (opts & QInputDialog::UsePlainTextEditForTextInput) {
+ ensurePlainTextEdit();
+ widget = plainTextEdit;
} else {
ensureLineEdit();
widget = lineEdit;
@@ -417,6 +441,16 @@ void QInputDialogPrivate::_q_textChanged(const QString &text)
}
}
+void QInputDialogPrivate::_q_plainTextEditTextChanged()
+{
+ Q_Q(QInputDialog);
+ QString text = plainTextEdit->toPlainText();
+ if (textValue != text) {
+ textValue = text;
+ emit q->textValueChanged(text);
+ }
+}
+
void QInputDialogPrivate::_q_currentRowChanged(const QModelIndex &newIndex,
const QModelIndex & /* oldIndex */)
{
@@ -434,8 +468,8 @@ void QInputDialogPrivate::_q_currentRowChanged(const QModelIndex &newIndex,
The input value can be a string, a number or an item from a list. A label
must be set to tell the user what they should enter.
- Four static convenience functions are provided: getText(), getInt(),
- getDouble(), and getItem(). All the functions can be used in a similar way,
+ Five static convenience functions are provided: getText(), getMultiLineText(),
+ getInt(), getDouble(), and getItem(). All the functions can be used in a similar way,
for example:
\snippet dialogs/standarddialogs/dialog.cpp 3
@@ -575,6 +609,8 @@ QString QInputDialog::labelText() const
\value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons (useful for "live dialogs").
\value UseListViewForComboBoxItems Use a QListView rather than a non-editable QComboBox for
displaying the items set with setComboBoxItems().
+ \value UsePlainTextEditForTextInput Use a QPlainTextEdit for multiline text input. This value was
+ introduced in 5.2.
\sa options, setOption(), testOption()
*/
@@ -628,6 +664,8 @@ void QInputDialog::setOptions(InputDialogOptions options)
d->buttonBox->setVisible(!(options & NoButtons));
if ((changed & UseListViewForComboBoxItems) && inputMode() == TextInput)
d->chooseRightTextInputWidget();
+ if ((changed & UsePlainTextEditForTextInput) && inputMode() == TextInput)
+ d->chooseRightTextInputWidget();
}
QInputDialog::InputDialogOptions QInputDialog::options() const
@@ -653,6 +691,8 @@ void QInputDialog::setTextValue(const QString &text)
setInputMode(TextInput);
if (d->inputWidget == d->lineEdit) {
d->lineEdit->setText(text);
+ } else if (d->inputWidget == d->plainTextEdit) {
+ d->plainTextEdit->setPlainText(text);
} else if (d->inputWidget == d->comboBox) {
d->setComboBoxText(text);
} else {
@@ -1075,6 +1115,8 @@ void QInputDialog::setVisible(bool visible)
d->inputWidget->setFocus();
if (d->inputWidget == d->lineEdit) {
d->lineEdit->selectAll();
+ } else if (d->inputWidget == d->plainTextEdit) {
+ d->plainTextEdit->selectAll();
} else if (d->inputWidget == d->intSpinBox) {
d->intSpinBox->selectAll();
} else if (d->inputWidget == d->doubleSpinBox) {
@@ -1144,7 +1186,7 @@ void QInputDialog::done(int result)
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getInt(), getDouble(), getItem()
+ \sa getInt(), getDouble(), getItem(), getMultiLineText()
*/
QString QInputDialog::getText(QWidget *parent, const QString &title, const QString &label,
@@ -1169,6 +1211,58 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri
}
/*!
+ \since 5.2
+
+ Static convenience function to get a multiline string from the user.
+
+ \a title is the text which is displayed in the title bar of the dialog.
+ \a label is the text which is shown to the user (it should say what should
+ be entered).
+ \a text is the default text which is placed in the plain text edit.
+ \a inputMethodHints is the input method hints that will be used in the
+ edit widget if an input method is active.
+
+ If \a ok is nonnull \e *\a ok will be set to true if the user pressed
+ \uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
+ is \a parent. The dialog will be modal and uses the specified widget
+ \a flags.
+
+ If the dialog is accepted, this function returns the text in the dialog's
+ plain text edit. If the dialog is rejected, a null QString is returned.
+
+ Use this static function like this:
+
+ \snippet dialogs/standarddialogs/dialog.cpp 4
+
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QInputDialog constructors.
+
+ \sa getInt(), getDouble(), getItem(), getText()
+*/
+
+QString QInputDialog::getMultiLineText(QWidget *parent, const QString &title, const QString &label,
+ const QString &text, bool *ok, Qt::WindowFlags flags,
+ Qt::InputMethodHints inputMethodHints)
+{
+ QInputDialog dialog(parent, flags);
+ dialog.setOptions(QInputDialog::UsePlainTextEditForTextInput);
+ dialog.setWindowTitle(title);
+ dialog.setLabelText(label);
+ dialog.setTextValue(text);
+ dialog.setInputMethodHints(inputMethodHints);
+
+ int ret = dialog.exec();
+ if (ok)
+ *ok = !!ret;
+ if (ret) {
+ return dialog.textValue();
+ } else {
+ return QString();
+ }
+}
+
+/*!
\since 4.5
Static convenience function to get an integer input from the user.
@@ -1196,7 +1290,7 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getDouble(), getItem()
+ \sa getText(), getDouble(), getItem(), getMultiLineText()
*/
int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &label, int value,
@@ -1248,7 +1342,7 @@ int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &l
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getDouble(), getItem()
+ \sa getText(), getDouble(), getItem(), getMultiLineText()
*/
/*!
@@ -1277,7 +1371,7 @@ int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &l
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getInt(), getItem()
+ \sa getText(), getInt(), getItem(), getMultiLineText()
*/
double QInputDialog::getDouble(QWidget *parent, const QString &title, const QString &label,
@@ -1331,7 +1425,7 @@ double QInputDialog::getDouble(QWidget *parent, const QString &title, const QStr
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getInt(), getDouble()
+ \sa getText(), getInt(), getDouble(), getMultiLineText()
*/
QString QInputDialog::getItem(QWidget *parent, const QString &title, const QString &label,
diff --git a/src/widgets/dialogs/qinputdialog.h b/src/widgets/dialogs/qinputdialog.h
index 41dca1f94f..c2c85835c8 100644
--- a/src/widgets/dialogs/qinputdialog.h
+++ b/src/widgets/dialogs/qinputdialog.h
@@ -78,8 +78,9 @@ class Q_WIDGETS_EXPORT QInputDialog : public QDialog
public:
enum InputDialogOption {
- NoButtons = 0x00000001,
- UseListViewForComboBoxItems = 0x00000002
+ NoButtons = 0x00000001,
+ UseListViewForComboBoxItems = 0x00000002,
+ UsePlainTextEditForTextInput = 0x00000004
};
Q_DECLARE_FLAGS(InputDialogOptions, InputDialogOption)
@@ -168,6 +169,9 @@ public:
QLineEdit::EchoMode echo = QLineEdit::Normal,
const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0,
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
+ static QString getMultiLineText(QWidget *parent, const QString &title, const QString &label,
+ const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0,
+ Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
static QString getItem(QWidget *parent, const QString &title, const QString &label,
const QStringList &items, int current = 0, bool editable = true,
bool *ok = 0, Qt::WindowFlags flags = 0,
@@ -204,6 +208,7 @@ public:
private:
Q_DISABLE_COPY(QInputDialog)
Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString&))
+ Q_PRIVATE_SLOT(d_func(), void _q_plainTextEditTextChanged())
Q_PRIVATE_SLOT(d_func(), void _q_currentRowChanged(const QModelIndex&, const QModelIndex&))
};
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 995d279e13..e51143cb7e 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -201,6 +201,7 @@ public:
detectedEscapeButton(0), informativeLabel(0) { }
void init(const QString &title = QString(), const QString &text = QString());
+ void setupLayout();
void _q_buttonClicked(QAbstractButton *);
QAbstractButton *findButton(int button0, int button1, int button2, int flags);
@@ -271,7 +272,6 @@ void QMessageBoxPrivate::init(const QString &title, const QString &text)
label->setContentsMargins(2, 0, 0, 0);
label->setIndent(9);
#endif
- icon = QMessageBox::NoIcon;
iconLabel = new QLabel;
iconLabel->setObjectName(QLatin1String("qt_msgboxex_icon_label"));
iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
@@ -281,41 +281,50 @@ void QMessageBoxPrivate::init(const QString &title, const QString &text)
buttonBox->setCenterButtons(q->style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, q));
QObject::connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
q, SLOT(_q_buttonClicked(QAbstractButton*)));
+ setupLayout();
+ if (!title.isEmpty() || !text.isEmpty()) {
+ q->setWindowTitle(title);
+ q->setText(text);
+ }
+ q->setModal(true);
+#ifdef Q_OS_MAC
+ QFont f = q->font();
+ f.setBold(true);
+ label->setFont(f);
+#endif
+ icon = QMessageBox::NoIcon;
+}
+void QMessageBoxPrivate::setupLayout()
+{
+ Q_Q(QMessageBox);
+ delete q->layout();
QGridLayout *grid = new QGridLayout;
-#ifndef Q_OS_MAC
grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop);
grid->addWidget(label, 0, 1, 1, 1);
- // -- leave space for information label --
+ if (informativeLabel)
+ grid->addWidget(informativeLabel, 1, 1, 1, 1);
+#ifndef Q_OS_MAC
grid->addWidget(buttonBox, 2, 0, 1, 2);
#else
+ grid->addWidget(buttonBox, 3, 1, 1, 1);
+#endif
+ if (detailsText)
+ grid->addWidget(detailsText, grid->rowCount(), 0, 1, grid->columnCount());
+#ifdef Q_OS_MAC
grid->setMargin(0);
grid->setVerticalSpacing(8);
grid->setHorizontalSpacing(0);
q->setContentsMargins(24, 15, 24, 20);
- grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop | Qt::AlignLeft);
- grid->addWidget(label, 0, 1, 1, 1);
- // -- leave space for information label --
grid->setRowStretch(1, 100);
grid->setRowMinimumHeight(2, 6);
- grid->addWidget(buttonBox, 3, 1, 1, 1);
#endif
grid->setSizeConstraint(QLayout::SetNoConstraint);
q->setLayout(grid);
- if (!title.isEmpty() || !text.isEmpty()) {
- q->setWindowTitle(title);
- q->setText(text);
- }
- q->setModal(true);
-
-#ifdef Q_OS_MAC
- QFont f = q->font();
- f.setBold(true);
- label->setFont(f);
-#endif
retranslateStrings();
+ updateSize();
}
int QMessageBoxPrivate::layoutMinimumWidth()
@@ -2458,24 +2467,27 @@ void QMessageBox::setDetailedText(const QString &text)
{
Q_D(QMessageBox);
if (text.isEmpty()) {
- delete d->detailsText;
+ if (d->detailsText) {
+ d->detailsText->hide();
+ d->detailsText->deleteLater();
+ }
d->detailsText = 0;
removeButton(d->detailsButton);
- delete d->detailsButton;
+ if (d->detailsButton) {
+ d->detailsButton->hide();
+ d->detailsButton->deleteLater();
+ }
d->detailsButton = 0;
- return;
- }
-
- if (!d->detailsText) {
- d->detailsText = new QMessageBoxDetailsText(this);
- QGridLayout* grid = qobject_cast<QGridLayout*>(layout());
- if (grid)
- grid->addWidget(d->detailsText, grid->rowCount(), 0, 1, grid->columnCount());
- d->detailsText->hide();
+ } else {
+ if (!d->detailsText) {
+ d->detailsText = new QMessageBoxDetailsText(this);
+ d->detailsText->hide();
+ }
+ if (!d->detailsButton)
+ d->detailsButton = new DetailButton(this);
+ d->detailsText->setText(text);
}
- if (!d->detailsButton)
- d->detailsButton = new DetailButton(this);
- d->detailsText->setText(text);
+ d->setupLayout();
}
#endif // QT_NO_TEXTEDIT
@@ -2506,39 +2518,37 @@ void QMessageBox::setInformativeText(const QString &text)
{
Q_D(QMessageBox);
if (text.isEmpty()) {
- layout()->removeWidget(d->informativeLabel);
- delete d->informativeLabel;
+ if (d->informativeLabel) {
+ d->informativeLabel->hide();
+ d->informativeLabel->deleteLater();
+ }
d->informativeLabel = 0;
#ifndef Q_OS_MAC
d->label->setContentsMargins(2, 0, 0, 0);
#endif
- d->updateSize();
- return;
- }
-
- if (!d->informativeLabel) {
- QLabel *label = new QLabel;
- label->setObjectName(QLatin1String("qt_msgbox_informativelabel"));
- label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this)));
- label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
- label->setOpenExternalLinks(true);
- label->setWordWrap(true);
+ } else {
+ if (!d->informativeLabel) {
+ QLabel *label = new QLabel;
+ label->setObjectName(QLatin1String("qt_msgbox_informativelabel"));
+ label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this)));
+ label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+ label->setOpenExternalLinks(true);
+ label->setWordWrap(true);
#ifndef Q_OS_MAC
- d->label->setContentsMargins(2, 0, 0, 0);
- label->setContentsMargins(2, 0, 0, 6);
- label->setIndent(9);
+ d->label->setContentsMargins(2, 0, 0, 0);
+ label->setContentsMargins(2, 0, 0, 6);
+ label->setIndent(9);
#else
- label->setContentsMargins(16, 0, 0, 0);
- // apply a smaller font the information label on the mac
- label->setFont(qt_app_fonts_hash()->value("QTipLabel"));
+ label->setContentsMargins(16, 0, 0, 0);
+ // apply a smaller font the information label on the mac
+ label->setFont(qt_app_fonts_hash()->value("QTipLabel"));
#endif
- label->setWordWrap(true);
- QGridLayout *grid = static_cast<QGridLayout *>(layout());
- grid->addWidget(label, 1, 1, 1, 1);
- d->informativeLabel = label;
+ label->setWordWrap(true);
+ d->informativeLabel = label;
+ }
+ d->informativeLabel->setText(text);
}
- d->informativeLabel->setText(text);
- d->updateSize();
+ d->setupLayout();
}
/*!
diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf
index a989ef9363..d3c7825bc0 100644
--- a/src/widgets/doc/qtwidgets.qdocconf
+++ b/src/widgets/doc/qtwidgets.qdocconf
@@ -54,3 +54,6 @@ imagedirs += images \
../../../doc/src/images \
../../../examples/widgets/doc/images \
../../../examples/widgets
+
+navigation.landingpage = "Qt Widgets"
+navigation.cppclassespage = "Qt Widgets C++ Classes"
diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
index a253c09d8b..f0010b6f25 100644
--- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
+++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
@@ -129,3 +129,14 @@ QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
//! [12]
+
+//! [13]
+QStringList mimeTypeFilters;
+mimeTypeFilters << "image/jpeg" // will show "JPEG image (*.jpeg *.jpg *.jpe)
+ << "image/png" // will show "PNG image (*.png)"
+ << "application/octet-stream"; // will show "All files (*)"
+
+QFileDialog dialog(this);
+dialog.setMimeTypeFilters(mimeTypeFilters);
+dialog.exec();
+//! [13]
diff --git a/src/widgets/doc/src/qtwidgets-examples.qdoc b/src/widgets/doc/src/qtwidgets-examples.qdoc
index 7111eb81b0..985aa24749 100644
--- a/src/widgets/doc/src/qtwidgets-examples.qdoc
+++ b/src/widgets/doc/src/qtwidgets-examples.qdoc
@@ -112,7 +112,7 @@
/*!
\ingroup all-examples
- \title Itemview Examples
+ \title Item Views Examples
\brief Using the model/view framework.
\group examples-itemviews
diff --git a/src/widgets/doc/src/qtwidgets.qdoc b/src/widgets/doc/src/qtwidgets.qdoc
index 2e3403e9d9..e6145ea17e 100644
--- a/src/widgets/doc/src/qtwidgets.qdoc
+++ b/src/widgets/doc/src/qtwidgets.qdoc
@@ -29,6 +29,7 @@
\module QtWidgets
\title Qt Widgets C++ Classes
\ingroup modules
+ \qtvariable widgets
\brief The Qt Widgets module extends Qt GUI with C++ widget functionality.
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index bb6033ba6c..47c05d4a46 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -844,8 +844,8 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch
// Inherit the enabled-state from our parents.
if ((parent->d_ptr->ancestorFlags & flag)
|| (int(parent->d_ptr->flags & childFlag) == childFlag)
- || (childFlag == -1 && parent->d_ptr->handlesChildEvents)
- || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
+ || (int(childFlag) == -1 && parent->d_ptr->handlesChildEvents)
+ || (int(childFlag) == -2 && parent->d_ptr->filtersDescendantEvents)) {
enabled = true;
ancestorFlags |= flag;
} else {
@@ -868,7 +868,7 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch
ancestorFlags &= ~flag;
// Don't process children if the item has the main flag set on itself.
- if ((childFlag != -1 && int(flags & childFlag) == childFlag)
+ if ((int(childFlag) != -1 && int(flags & childFlag) == childFlag)
|| (int(childFlag) == -1 && handlesChildEvents)
|| (int(childFlag) == -2 && filtersDescendantEvents))
return;
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
index 45e8b436b1..55d7ee6d1b 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
@@ -93,6 +93,8 @@
#include <QtCore/qpair.h>
#include <QtGui/qmatrix.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
class QGraphicsItemAnimationPrivate
@@ -179,7 +181,7 @@ void QGraphicsItemAnimationPrivate::insertUniquePair(qreal step, qreal value, QL
result->value = value;
else {
*binList << pair;
- qSort(binList->begin(), binList->end());
+ std::sort(binList->begin(), binList->end());
}
}
diff --git a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
index f70e66f685..7598163f2d 100644
--- a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -567,10 +567,7 @@ QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co
itemList << item;
}
}
- if (order != -1) {
- //We sort descending order
- d->sortItems(&itemList, order, d->sortCacheEnabled);
- }
+ d->sortItems(&itemList, order, d->sortCacheEnabled);
return itemList;
}
diff --git a/src/widgets/graphicsview/qgridlayoutengine.cpp b/src/widgets/graphicsview/qgridlayoutengine.cpp
index 4f43a0a4ac..f741962264 100644
--- a/src/widgets/graphicsview/qgridlayoutengine.cpp
+++ b/src/widgets/graphicsview/qgridlayoutengine.cpp
@@ -432,6 +432,8 @@ QGridLayoutBox QGridLayoutRowData::totalBox(int start, int end) const
result.q_maximumSize = 0.0;
qreal nextSpacing = 0.0;
for (int i = start; i < end; ++i) {
+ if (ignore.testBit(i))
+ continue;
result.add(boxes.at(i), stretches.at(i), nextSpacing);
nextSpacing = spacings.at(i);
}
@@ -1475,7 +1477,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
int effectiveRowSpan = 1;
for (int i = 1; i < itemRowSpan; ++i) {
- if (!rowData->ignore.testBit(i))
+ if (!rowData->ignore.testBit(i + itemRow))
++effectiveRowSpan;
}
@@ -1713,7 +1715,8 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
q_descents.resize(rowCount());
if (constraintOrientation() != Qt::Horizontal) {
- //We might have items whose width depends on their height
+ // We might have items whose height depends on their width,
+ // or none of the items has a dynamic constraint.
ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
//Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
//constraints to find the row heights
@@ -1724,7 +1727,7 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
} else {
- //We have items whose height depends on their width
+ // We have items whose width depends on their height
ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
//constraints to find the column widths
diff --git a/src/widgets/itemviews/itemviews.pri b/src/widgets/itemviews/itemviews.pri
index 0bc0309271..4e152d18bb 100644
--- a/src/widgets/itemviews/itemviews.pri
+++ b/src/widgets/itemviews/itemviews.pri
@@ -26,6 +26,7 @@ HEADERS += \
itemviews/qtreewidgetitemiterator.h \
itemviews/qdatawidgetmapper.h \
itemviews/qfileiconprovider.h \
+ itemviews/qfileiconprovider_p.h \
itemviews/qcolumnviewgrip_p.h \
itemviews/qcolumnview.h \
itemviews/qcolumnview_p.h \
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 70c8f44a73..b79525b9df 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1108,6 +1108,7 @@ void QAbstractItemView::reset()
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ d->updateGeometry();
}
/*!
@@ -1124,6 +1125,7 @@ void QAbstractItemView::setRootIndex(const QModelIndex &index)
}
d->root = index;
d->doDelayedItemsLayout();
+ d->updateGeometry();
}
/*!
@@ -2668,8 +2670,10 @@ void QAbstractItemView::updateEditorGeometries()
*/
void QAbstractItemView::updateGeometries()
{
+ Q_D(QAbstractItemView);
updateEditorGeometries();
- d_func()->fetchMoreTimer.start(0, this); //fetch more later
+ d->fetchMoreTimer.start(0, this); //fetch more later
+ d->updateGeometry();
}
/*!
@@ -3231,6 +3235,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ d->updateGeometry();
}
/*!
@@ -3332,6 +3337,7 @@ void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int star
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -3412,6 +3418,7 @@ void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int s
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
@@ -3435,6 +3442,7 @@ void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int sta
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -3459,6 +3467,7 @@ void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -4084,7 +4093,14 @@ void QAbstractItemViewPrivate::interruptDelayedItemsLayout() const
delayedPendingLayout = false;
}
-
+void QAbstractItemViewPrivate::updateGeometry()
+{
+ Q_Q(QAbstractItemView);
+ if (sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
+ return;
+ if (sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents || !shownOnce)
+ q->updateGeometry();
+}
QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index 86eab174ed..5da22615e2 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -127,6 +127,8 @@ public:
void doDelayedItemsLayout(int delay = 0);
void interruptDelayedItemsLayout() const;
+ void updateGeometry();
+
void startAutoScroll()
{ // ### it would be nice to make this into a style hint one day
int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50;
diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp
index 5aee78fab4..32a3dddca1 100644
--- a/src/widgets/itemviews/qcolumnview.cpp
+++ b/src/widgets/itemviews/qcolumnview.cpp
@@ -332,11 +332,14 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint)
}
#ifndef QT_NO_ANIMATION
- d->currentAnimation.setEndValue(newScrollbarValue);
- d->currentAnimation.start();
-#else
- horizontalScrollBar()->setValue(newScrollbarValue);
+ if (style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) {
+ d->currentAnimation.setEndValue(newScrollbarValue);
+ d->currentAnimation.start();
+ } else
#endif //QT_NO_ANIMATION
+ {
+ horizontalScrollBar()->setValue(newScrollbarValue);
+ }
}
/*!
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index 8a0736ec70..71697ddc40 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -40,9 +40,8 @@
****************************************************************************/
#include "qfileiconprovider.h"
+#include "qfileiconprovider_p.h"
-#ifndef QT_NO_FILEICONPROVIDER
-#include <qstyle.h>
#include <qapplication.h>
#include <qdir.h>
#include <qpixmapcache.h>
@@ -83,34 +82,15 @@ QT_BEGIN_NAMESPACE
\value File
*/
-class QFileIconProviderPrivate
-{
- Q_DECLARE_PUBLIC(QFileIconProvider)
-
-public:
- QFileIconProviderPrivate();
- QIcon getIcon(QStyle::StandardPixmap name) const;
- QIcon getIcon(const QFileInfo &fi) const;
-
- QFileIconProvider *q_ptr;
- const QString homePath;
-
-private:
- mutable QIcon file;
- mutable QIcon fileLink;
- mutable QIcon directory;
- mutable QIcon directoryLink;
- mutable QIcon harddisk;
- mutable QIcon floppy;
- mutable QIcon cdrom;
- mutable QIcon ram;
- mutable QIcon network;
- mutable QIcon computer;
- mutable QIcon desktop;
- mutable QIcon trashcan;
- mutable QIcon generic;
- mutable QIcon home;
-};
+
+/*!
+ \enum QFileIconProvider::Option
+ \since 5.2
+
+ \value DontUseCustomDirectoryIcons Always use the default directory icon.
+ Some platforms allow the user to set a different icon. Custom icon lookup
+ cause a big performance impact over network or removable drives.
+*/
QFileIconProviderPrivate::QFileIconProviderPrivate() :
homePath(QDir::home().absolutePath())
@@ -193,6 +173,31 @@ QFileIconProvider::~QFileIconProvider()
}
/*!
+ \since 5.2
+ Sets \a options that affect the icon provider.
+ \sa options()
+*/
+
+void QFileIconProvider::setOptions(QFileIconProvider::Options options)
+{
+ Q_D(QFileIconProvider);
+ d->options = options;
+}
+
+/*!
+ \since 5.2
+ Returns all the options that affect the icon provider.
+ By default, all options are disabled.
+ \sa setOptions()
+*/
+
+QFileIconProvider::Options QFileIconProvider::options() const
+{
+ Q_D(const QFileIconProvider);
+ return d->options;
+}
+
+/*!
Returns an icon set for the given \a type.
*/
@@ -220,6 +225,23 @@ QIcon QFileIconProvider::icon(IconType type) const
return QIcon();
}
+static bool isCacheable(const QFileInfo &fi)
+{
+ if (!fi.isFile())
+ return false;
+
+#ifdef Q_OS_WIN
+ // On windows it's faster to just look at the file extensions. QTBUG-13182
+ const QString fileExtension = fi.suffix();
+ // Will return false for .exe, .lnk and .ico extensions
+ return fileExtension.compare(QLatin1String("exe"), Qt::CaseInsensitive) &&
+ fileExtension.compare(QLatin1String("lnk"), Qt::CaseInsensitive) &&
+ fileExtension.compare(QLatin1String("ico"), Qt::CaseInsensitive);
+#else
+ return !fi.isExecutable() && !fi.isSymLink();
+#endif
+}
+
QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
{
QIcon retIcon;
@@ -231,10 +253,9 @@ QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
if (sizes.isEmpty())
return retIcon;
- const QString fileExtension = fi.suffix().toUpper();
const QString keyBase = QLatin1String("qt_.") + fi.suffix().toUpper();
- bool cacheable = fi.isFile() && !fi.isExecutable() && !fi.isSymLink() && fileExtension != QLatin1String("ICO");
+ bool cacheable = isCacheable(fi);
if (cacheable) {
QPixmap pixmap;
QPixmapCache::find(keyBase + QString::number(sizes.at(0)), pixmap);
@@ -253,8 +274,12 @@ QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
}
}
+ QPlatformTheme::IconOptions iconOptions;
+ if (options & QFileIconProvider::DontUseCustomDirectoryIcons)
+ iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons;
+
Q_FOREACH (int size, sizes) {
- QPixmap pixmap = theme->fileIconPixmap(fi, QSizeF(size, size));
+ QPixmap pixmap = theme->fileIconPixmap(fi, QSizeF(size, size), iconOptions);
if (!pixmap.isNull()) {
retIcon.addPixmap(pixmap);
if (cacheable)
@@ -372,5 +397,3 @@ QString QFileIconProvider::type(const QFileInfo &info) const
}
QT_END_NAMESPACE
-
-#endif
diff --git a/src/widgets/itemviews/qfileiconprovider.h b/src/widgets/itemviews/qfileiconprovider.h
index cac135fe71..6f7e28395b 100644
--- a/src/widgets/itemviews/qfileiconprovider.h
+++ b/src/widgets/itemviews/qfileiconprovider.h
@@ -49,8 +49,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_FILEICONPROVIDER
-
class QFileIconProviderPrivate;
class Q_WIDGETS_EXPORT QFileIconProvider
@@ -59,19 +57,27 @@ public:
QFileIconProvider();
virtual ~QFileIconProvider();
enum IconType { Computer, Desktop, Trashcan, Network, Drive, Folder, File };
+
+ enum Option {
+ DontUseCustomDirectoryIcons = 0x00000001
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
virtual QIcon icon(IconType type) const;
virtual QIcon icon(const QFileInfo &info) const;
virtual QString type(const QFileInfo &info) const;
+ void setOptions(Options options);
+ Options options() const;
+
private:
Q_DECLARE_PRIVATE(QFileIconProvider)
QScopedPointer<QFileIconProviderPrivate> d_ptr;
Q_DISABLE_COPY(QFileIconProvider)
};
-#endif // QT_NO_FILEICONPROVIDER
+Q_DECLARE_OPERATORS_FOR_FLAGS(QFileIconProvider::Options)
QT_END_NAMESPACE
#endif // QFILEICONPROVIDER_H
-
diff --git a/src/widgets/itemviews/qfileiconprovider_p.h b/src/widgets/itemviews/qfileiconprovider_p.h
new file mode 100644
index 0000000000..9b2d536258
--- /dev/null
+++ b/src/widgets/itemviews/qfileiconprovider_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILEICONPROVIDER_P_H
+#define QFILEICONPROVIDER_P_H
+
+#include "qfileiconprovider.h"
+
+#include <QtCore/qstring.h>
+#include <QtGui/qicon.h>
+#include <QtWidgets/qstyle.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFileInfo;
+
+class QFileIconProviderPrivate
+{
+ Q_DECLARE_PUBLIC(QFileIconProvider)
+
+public:
+ QFileIconProviderPrivate();
+ QIcon getIcon(QStyle::StandardPixmap name) const;
+ QIcon getIcon(const QFileInfo &fi) const;
+
+ QFileIconProvider *q_ptr;
+ const QString homePath;
+ QFileIconProvider::Options options;
+
+private:
+ mutable QIcon file;
+ mutable QIcon fileLink;
+ mutable QIcon directory;
+ mutable QIcon directoryLink;
+ mutable QIcon harddisk;
+ mutable QIcon floppy;
+ mutable QIcon cdrom;
+ mutable QIcon ram;
+ mutable QIcon network;
+ mutable QIcon computer;
+ mutable QIcon desktop;
+ mutable QIcon trashcan;
+ mutable QIcon generic;
+ mutable QIcon home;
+};
+
+QT_END_NAMESPACE
+
+#endif // QFILEICONPROVIDER_P_H
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 864a55d2ea..239cc84a0a 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -80,6 +80,8 @@ QDataStream &operator>>(QDataStream &in, QHeaderViewPrivate::SectionItem &sectio
}
#endif // QT_NO_DATASTREAM
+static const int maxSizeSection = 1048575; // since section size is in a bitfield (uint 20). See qheaderview_p.h
+ // if this is changed then the docs in maximumSectionSize should be changed.
/*!
\class QHeaderView
@@ -550,9 +552,25 @@ QSize QHeaderView::sizeHint() const
}
/*!
+ \reimp
+*/
+
+void QHeaderView::setVisible(bool v)
+{
+ bool actualChange = (v != isVisible());
+ QAbstractItemView::setVisible(v);
+ if (actualChange) {
+ QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea*>(parentWidget());
+ if (parent)
+ parent->updateGeometry();
+ }
+}
+
+
+/*!
Returns a suitable size hint for the section specified by \a logicalIndex.
- \sa sizeHint(), defaultSectionSize(), minimumSectionSize(),
+ \sa sizeHint(), defaultSectionSize(), minimumSectionSize(), maximumSectionSize()
Qt::SizeHintRole
*/
@@ -570,7 +588,7 @@ int QHeaderView::sectionSizeHint(int logicalIndex) const
else
size = sectionSizeFromContents(logicalIndex);
int hint = d->orientation == Qt::Horizontal ? size.width() : size.height();
- return qMax(minimumSectionSize(), hint);
+ return qBound(minimumSectionSize(), hint, maximumSectionSize());
}
/*!
@@ -868,7 +886,7 @@ void QHeaderView::swapSections(int first, int second)
void QHeaderView::resizeSection(int logical, int size)
{
Q_D(QHeaderView);
- if (logical < 0 || logical >= count() || size < 0)
+ if (logical < 0 || logical >= count() || size < 0 || size > maxSizeSection)
return;
if (isSectionHidden(logical)) {
@@ -918,6 +936,18 @@ void QHeaderView::resizeSection(int logical, int size)
d->doDelayedResizeSections();
r = d->viewport->rect();
}
+
+ // If the parent is a QAbstractScrollArea with QAbstractScrollArea::AdjustToContents
+ // then we want to change the geometry on that widget. Not doing it at once can/will
+ // cause scrollbars flicker as they would be shown at first but then removed.
+ // In the same situation it will also allow shrinking the whole view when stretchLastSection is set
+ // (It is default on QTreeViews - and it wouldn't shrink since the last stretch was made before the
+ // viewport was resized)
+
+ QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea *>(parentWidget());
+ if (parent && parent->sizeAdjustPolicy() == QAbstractScrollArea::AdjustToContents)
+ parent->updateGeometry();
+
d->viewport->update(r.normalized());
emit sectionResized(logical, oldSize, size);
}
@@ -1225,7 +1255,7 @@ void QHeaderView::setSectionResizeMode(ResizeMode mode)
property is set to true. This is the default for the horizontal headers provided
by QTreeView.
- \sa setStretchLastSection()
+ \sa setStretchLastSection(), resizeContentsPrecision()
*/
void QHeaderView::setSectionResizeMode(int logicalIndex, ResizeMode mode)
@@ -1288,6 +1318,53 @@ QHeaderView::ResizeMode QHeaderView::sectionResizeMode(int logicalIndex) const
return d->headerSectionResizeMode(visual);
}
+/*!
+ \since 5.2
+ Sets how precise QHeaderView should calculate the size when ResizeToContents is used.
+ A low value will provide a less accurate but fast auto resize while a higher
+ value will provide a more accurate resize that however can be slow.
+
+ The number \a precision specifies how many sections that should be consider
+ when calculating the preferred size.
+
+ The default value is 1000 meaning that a horizontal column with auto-resize will look
+ at maximum 1000 rows on calculating when doing an auto resize.
+
+ Special value 0 means that it will look at only the visible area.
+ Special value -1 will imply looking at all elements.
+
+ This value is used in QTableView::sizeHintForColumn(), QTableView::sizeHintForRow()
+ and QTreeView::sizeHintForColumn(). Reimplementing these functions can make this
+ function not having an effect.
+
+ If \a resizeSectionsNow is set to true (default) it will do adjustment of sections by calling
+ resizeSections(). (regardless if the precision was changed).
+
+ \sa resizeContentsPrecision(), setSectionResizeMode(), resizeSections(), QTableView::sizeHintForColumn(), QTableView::sizeHintForRow(), QTreeView::sizeHintForColumn()
+*/
+
+void QHeaderView::setResizeContentsPrecision(int precision, bool resizeSectionsNow)
+{
+ Q_D(QHeaderView);
+ d->resizeContentsPrecision = precision;
+ if (resizeSectionsNow)
+ resizeSections();
+}
+
+/*!
+ \since 5.2
+ Returns how precise QHeaderView will calculate on ResizeToContents.
+
+ \sa setResizeContentsPrecision(), setSectionResizeMode()
+
+*/
+
+int QHeaderView::resizeContentsPrecision() const
+{
+ Q_D(const QHeaderView);
+ return d->resizeContentsPrecision;
+}
+
// ### Qt 6 - remove this obsolete function
/*!
\obsolete
@@ -1492,7 +1569,7 @@ int QHeaderView::defaultSectionSize() const
void QHeaderView::setDefaultSectionSize(int size)
{
Q_D(QHeaderView);
- if (size < 0)
+ if (size < 0 || size > maxSizeSection)
return;
d->setDefaultSectionSize(size);
}
@@ -1527,12 +1604,52 @@ int QHeaderView::minimumSectionSize() const
void QHeaderView::setMinimumSectionSize(int size)
{
Q_D(QHeaderView);
- if (size < 0)
+ if (size < 0 || size > maxSizeSection)
return;
d->minimumSectionSize = size;
+ if (d->minimumSectionSize > maximumSectionSize())
+ d->maximumSectionSize = size;
}
/*!
+ \since 5.2
+ \property QHeaderView::maximumSectionSize
+ \brief the maximum size of the header sections.
+
+ The maximum section size is the largest section size allowed.
+ The default value for this property is 1048575, which is also the largest
+ possible size for a section. Setting maximum to -1 will reset the value to
+ the largest section size.
+
+ With exception of stretch this property is honored by all \l{ResizeMode}{resize modes}
+
+ \sa setSectionResizeMode(), defaultSectionSize
+*/
+int QHeaderView::maximumSectionSize() const
+{
+ Q_D(const QHeaderView);
+ if (d->maximumSectionSize == -1)
+ return maxSizeSection;
+ return d->maximumSectionSize;
+}
+
+void QHeaderView::setMaximumSectionSize(int size)
+{
+ Q_D(QHeaderView);
+ if (size == -1) {
+ d->maximumSectionSize = maxSizeSection;
+ return;
+ }
+ if (size < 0 || size > maxSizeSection)
+ return;
+ if (minimumSectionSize() > size)
+ d->minimumSectionSize = size;
+
+ d->maximumSectionSize = size;
+}
+
+
+/*!
\since 4.1
\property QHeaderView::defaultAlignment
\brief the default alignment of the text in each header section
@@ -2341,7 +2458,8 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e)
d->cascadingResize(visual, d->headerSectionSize(visual) + delta);
} else {
int delta = d->reverse() ? d->firstPos - pos : pos - d->firstPos;
- resizeSection(d->section, qMax(d->originalSize + delta, minimumSectionSize()));
+ int newsize = qBound(minimumSectionSize(), d->originalSize + delta, maximumSectionSize());
+ resizeSection(d->section, newsize);
}
d->lastPos = pos;
return;
@@ -3160,6 +3278,8 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
int logicalIndex = q->logicalIndex(i);
sectionSize = qMax(viewSectionSizeHint(logicalIndex),
q->sectionSizeHint(logicalIndex));
+ if (sectionSize > q->maximumSectionSize())
+ sectionSize = q->maximumSectionSize();
}
section_sizes.append(sectionSize);
lengthToStretch -= sectionSize;
@@ -3492,7 +3612,7 @@ QHeaderView::ResizeMode QHeaderViewPrivate::headerSectionResizeMode(int visual)
{
if (visual < 0 || visual >= sectionItems.count())
return globalResizeMode;
- return sectionItems.at(visual).resizeMode;
+ return static_cast<QHeaderView::ResizeMode>(sectionItems.at(visual).resizeMode);
}
void QHeaderViewPrivate::setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode)
@@ -3530,6 +3650,19 @@ int QHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const
return visualIndex;
}
+void QHeaderViewPrivate::setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode)
+{
+ Q_Q(QHeaderView);
+ if (scrollMode == QAbstractItemView::ScrollPerItem) {
+ if (scrollBar->maximum() > 0 && scrollBar->value() == scrollBar->maximum())
+ q->setOffsetToLastSection();
+ else
+ q->setOffsetToSectionPosition(scrollBar->value());
+ } else {
+ q->setOffset(scrollBar->value());
+ }
+}
+
#ifndef QT_NO_DATASTREAM
void QHeaderViewPrivate::write(QDataStream &out) const
{
@@ -3560,6 +3693,8 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << int(globalResizeMode);
out << sectionItems;
+ if (out.version() >= QDataStream::Qt_5_2)
+ out << resizeContentsPrecision;
}
bool QHeaderViewPrivate::read(QDataStream &in)
@@ -3611,6 +3746,10 @@ bool QHeaderViewPrivate::read(QDataStream &in)
}
sectionItems = newSectionItems;
recalcSectionStartPos();
+
+ if (in.version() >= QDataStream::Qt_5_2)
+ in >> resizeContentsPrecision;
+
return true;
}
diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h
index 8fcd8d7a36..b3ed666aa6 100644
--- a/src/widgets/itemviews/qheaderview.h
+++ b/src/widgets/itemviews/qheaderview.h
@@ -61,6 +61,7 @@ class Q_WIDGETS_EXPORT QHeaderView : public QAbstractItemView
Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes WRITE setCascadingSectionResizes)
Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize)
Q_PROPERTY(int minimumSectionSize READ minimumSectionSize WRITE setMinimumSectionSize)
+ Q_PROPERTY(int maximumSectionSize READ maximumSectionSize WRITE setMaximumSectionSize)
Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment)
Q_ENUMS(ResizeMode)
@@ -84,6 +85,7 @@ public:
int offset() const;
int length() const;
QSize sizeHint() const;
+ void setVisible(bool v);
int sectionSizeHint(int logicalIndex) const;
int visualIndexAt(int position) const;
@@ -132,6 +134,10 @@ public:
ResizeMode sectionResizeMode(int logicalIndex) const;
void setSectionResizeMode(ResizeMode mode);
void setSectionResizeMode(int logicalIndex, ResizeMode mode);
+
+ void setResizeContentsPrecision(int precision, bool resizeNow = true);
+ int resizeContentsPrecision() const;
+
#if QT_DEPRECATED_SINCE(5, 0)
inline QT_DEPRECATED void setResizeMode(ResizeMode mode)
{ setSectionResizeMode(mode); }
@@ -161,6 +167,8 @@ public:
int minimumSectionSize() const;
void setMinimumSectionSize(int size);
+ int maximumSectionSize() const;
+ void setMaximumSectionSize(int size);
Qt::Alignment defaultAlignment() const;
void setDefaultAlignment(Qt::Alignment alignment);
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index f886430ba8..b2af821e9b 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -95,11 +95,13 @@ public:
stretchSections(0),
contentsSections(0),
minimumSectionSize(-1),
+ maximumSectionSize(-1),
lastSectionSize(0),
sectionIndicatorOffset(0),
sectionIndicator(0),
globalResizeMode(QHeaderView::Interactive),
- sectionStartposRecalc(true)
+ sectionStartposRecalc(true),
+ resizeContentsPrecision(1000)
{}
@@ -286,6 +288,7 @@ public:
int contentsSections;
int defaultSectionSize;
int minimumSectionSize;
+ int maximumSectionSize;
int lastSectionSize; // $$$
int sectionIndicatorOffset;
Qt::Alignment defaultAlignment;
@@ -293,26 +296,31 @@ public:
QHeaderView::ResizeMode globalResizeMode;
QList<QPersistentModelIndex> persistentHiddenSections;
mutable bool sectionStartposRecalc;
+ int resizeContentsPrecision;
// header sections
struct SectionItem {
- int size;
+ uint size : 20;
+ uint reservedForIsHidden : 1;
+ uint resizeMode : 5; // (holding QHeaderView::ResizeMode)
+ uint currentlyUnusedPadding : 6;
+
union { // This union is made in order to save space and ensure good vector performance (on remove)
mutable int calculated_startpos; // <- this is the primary used member.
mutable int tmpLogIdx; // When one of these 'tmp'-members has been used we call
int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true
}; // to ensure that calculated_startpos will be calculated afterwards.
- QHeaderView::ResizeMode resizeMode;
+
inline SectionItem() : size(0), resizeMode(QHeaderView::Interactive) {}
inline SectionItem(int length, QHeaderView::ResizeMode mode)
- : size(length), calculated_startpos(-1), resizeMode(mode) {}
+ : size(length), resizeMode(mode), calculated_startpos(-1) {}
inline int sectionSize() const { return size; }
inline int calculatedEndPos() const { return calculated_startpos + size; }
#ifndef QT_NO_DATASTREAM
inline void write(QDataStream &out) const
- { out << size; out << 1; out << (int)resizeMode; }
+ { out << static_cast<int>(size); out << 1; out << (int)resizeMode; }
inline void read(QDataStream &in)
- { in >> size; in >> tmpDataStreamSectionCount; int m; in >> m; resizeMode = (QHeaderView::ResizeMode)m; }
+ { int m; in >> m; size = m; in >> tmpDataStreamSectionCount; in >> m; resizeMode = m; }
#endif
};
@@ -343,6 +351,7 @@ public:
// other
int viewSectionSizeHint(int logical) const;
int adjustedVisualIndex(int visualIndex) const;
+ void setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode);
#ifndef QT_NO_DATASTREAM
void write(QDataStream &out) const;
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index c040322ba1..3e34568a12 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -1295,8 +1295,11 @@ bool QItemDelegate::editorEvent(QEvent *event,
return false;
}
- Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
- ? Qt::Unchecked : Qt::Checked);
+ Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
+ if (flags & Qt::ItemIsTristate)
+ state = ((Qt::CheckState)((state + 1) % 3));
+ else
+ state = (state == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
return model->setData(index, state, Qt::CheckStateRole);
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 3690b15650..331748eedc 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1833,18 +1833,18 @@ void QCommonListViewBase::removeHiddenRow(int row)
dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex()));
}
-void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
+void QCommonListViewBase::updateHorizontalScrollBar(const QSize & /*step*/)
{
- horizontalScrollBar()->setSingleStep(step.width() + spacing());
horizontalScrollBar()->setPageStep(viewport()->width());
horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width());
+ // we do not want to overwrite (a possible user set) single step
}
-void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
+void QCommonListViewBase::updateVerticalScrollBar(const QSize & /*step*/)
{
- verticalScrollBar()->setSingleStep(step.height() + spacing());
verticalScrollBar()->setPageStep(viewport()->height());
verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height());
+ // we do not want to overwrite (a possible user set) single step
}
void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 39d03124ce..27abfb8eb4 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -304,7 +304,7 @@ void QListModel::sort(int column, Qt::SortOrder order)
}
LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- qSort(sorting.begin(), sorting.end(), compare);
+ std::sort(sorting.begin(), sorting.end(), compare);
QModelIndexList fromIndexes;
QModelIndexList toIndexes;
for (int r = 0; r < sorting.count(); ++r) {
@@ -338,7 +338,7 @@ void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int en
}
LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- qSort(sorting.begin(), sorting.end(), compare);
+ std::sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes = persistentIndexList();
QModelIndexList newPersistentIndexes = oldPersistentIndexes;
@@ -347,7 +347,11 @@ void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int en
bool changed = false;
for (int i = 0; i < count; ++i) {
int oldRow = sorting.at(i).second;
+ int tmpitepos = lit - tmp.begin();
QListWidgetItem *item = tmp.takeAt(oldRow);
+ if (tmpitepos > tmp.size())
+ --tmpitepos;
+ lit = tmp.begin() + tmpitepos;
lit = sortedInsertionIterator(lit, tmp.end(), order, item);
int newRow = qMax(lit - tmp.begin(), 0);
lit = tmp.insert(lit, item);
@@ -1828,7 +1832,7 @@ void QListWidget::dropEvent(QDropEvent *event) {
if (persIndexes.contains(topIndex))
return;
- qSort(persIndexes); // The dropped items will remain in the same visual order.
+ std::sort(persIndexes.begin(), persIndexes.end()); // The dropped items will remain in the same visual order.
QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp
index 7e1933ad1e..c1fa9fe28e 100644
--- a/src/widgets/itemviews/qstyleditemdelegate.cpp
+++ b/src/widgets/itemviews/qstyleditemdelegate.cpp
@@ -764,8 +764,11 @@ bool QStyledItemDelegate::editorEvent(QEvent *event,
return false;
}
- Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
- ? Qt::Unchecked : Qt::Checked);
+ Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
+ if (flags & Qt::ItemIsTristate)
+ state = ((Qt::CheckState)((state + 1) % 3));
+ else
+ state = (state == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
return model->setData(index, state, Qt::CheckStateRole);
}
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index a6623b9462..871ad656ea 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -931,6 +931,59 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
}
/*!
+ \internal
+ Get sizeHint width for single Index (providing existing hint and style option)
+*/
+int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+{
+ Q_Q(const QTableView);
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+ int min = editor->minimumSize().width();
+ int max = editor->maximumSize().width();
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
+ return hint;
+}
+
+/*!
+ \internal
+ Get sizeHint height for single Index (providing existing hint and style option)
+*/
+int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QStyleOptionViewItem &option) const
+{
+ Q_Q(const QTableView);
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().height());
+ int min = editor->minimumSize().height();
+ int max = editor->maximumSize().height();
+ hint = qBound(min, hint, max);
+ }
+
+ if (wrapItemText) {// for wrapping boundaries
+ option.rect.setY(q->rowViewportPosition(index.row()));
+ int height = q->rowHeight(index.row());
+ // if the option.height == 0 then q->itemDelegate(index)->sizeHint(option, index) will be wrong.
+ // The option.height == 0 is used to conclude that the text is not wrapped, and hence it will
+ // (exactly like widthHintForIndex) return a QSize with a long width (that we don't use) -
+ // and the height of the text if it was/is on one line.
+ // What we want is a height hint for the current width (and we know that this section is not hidden)
+ // Therefore we catch this special situation with:
+ if (height == 0)
+ height = 1;
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).height());
+ return hint;
+}
+
+
+/*!
\class QTableView
\brief The QTableView class provides a default model/view
@@ -1056,6 +1109,19 @@ QTableView::~QTableView()
/*!
\reimp
*/
+QSize QTableView::viewportSizeHint() const
+{
+ Q_D(const QTableView);
+ QSize result( (d->verticalHeader->isHidden() ? 0 : d->verticalHeader->width()) + d->horizontalHeader->length(),
+ (d->horizontalHeader->isHidden() ? 0 : d->horizontalHeader->height()) + d->verticalHeader->length());
+ result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,
+ horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);
+ return result;
+}
+
+/*!
+ \reimp
+*/
void QTableView::setModel(QAbstractItemModel *model)
{
Q_D(QTableView);
@@ -1113,15 +1179,7 @@ void QTableView::doItemsLayout()
{
Q_D(QTableView);
QAbstractItemView::doItemsLayout();
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- const int max = verticalScrollBar()->maximum();
- if (max > 0 && verticalScrollBar()->value() == max)
- d->verticalHeader->setOffsetToLastSection();
- else
- d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value());
- } else {
- d->verticalHeader->setOffset(verticalScrollBar()->value());
- }
+ d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
if (!d->verticalHeader->updatesEnabled())
d->verticalHeader->setUpdatesEnabled(true);
}
@@ -1258,29 +1316,19 @@ void QTableView::scrollContentsBy(int dx, int dy)
dx = isRightToLeft() ? -dx : dx;
if (dx) {
+ int oldOffset = d->horizontalHeader->offset();
+ d->horizontalHeader->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode());
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->horizontalHeader->offset();
- if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum())
- d->horizontalHeader->setOffsetToLastSection();
- else
- d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value());
int newOffset = d->horizontalHeader->offset();
dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
- } else {
- d->horizontalHeader->setOffset(horizontalScrollBar()->value());
}
}
if (dy) {
+ int oldOffset = d->verticalHeader->offset();
+ d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->verticalHeader->offset();
- if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
- d->verticalHeader->setOffsetToLastSection();
- else
- d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value());
int newOffset = d->verticalHeader->offset();
dy = oldOffset - newOffset;
- } else {
- d->verticalHeader->setOffset(verticalScrollBar()->value());
}
}
d->scrollContentsBy(dx, dy);
@@ -1760,13 +1808,13 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
visualRow = bottom;
break;
case MovePageUp: {
- int newRow = rowAt(visualRect(current).top() - d->viewport->height());
+ int newRow = rowAt(visualRect(current).bottom() - d->viewport->height());
if (newRow == -1)
newRow = d->logicalRow(0);
return d->model->index(newRow, current.column(), d->root);
}
case MovePageDown: {
- int newRow = rowAt(visualRect(current).bottom() + d->viewport->height());
+ int newRow = rowAt(visualRect(current).top() + d->viewport->height());
if (newRow == -1)
newRow = d->logicalRow(bottom);
return d->model->index(newRow, current.column(), d->root);
@@ -2128,7 +2176,7 @@ void QTableView::updateGeometries()
} else { // ScrollPerPixel
horizontalScrollBar()->setPageStep(vsize.width());
horizontalScrollBar()->setRange(0, horizontalLength - vsize.width());
- horizontalScrollBar()->setSingleStep(qMax(vsize.width() / (columnsInViewport + 1), 2));
+ // here we do not want to overwrite (a possible user set) single step
}
// vertical scroll bar
@@ -2156,7 +2204,7 @@ void QTableView::updateGeometries()
} else { // ScrollPerPixel
verticalScrollBar()->setPageStep(vsize.height());
verticalScrollBar()->setRange(0, verticalLength - vsize.height());
- verticalScrollBar()->setSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
+ // here we do not want to overwrite (a possible user set) single step
}
d->geometryRecursionBlock = false;
@@ -2175,7 +2223,7 @@ void QTableView::updateGeometries()
if a larger row height is required by either the vertical header or
the item delegate, that width will be used instead.
- \sa QWidget::sizeHint, verticalHeader()
+ \sa QWidget::sizeHint, verticalHeader(), QHeaderView::resizeContentsPrecision()
*/
int QTableView::sizeHintForRow(int row) const
{
@@ -2185,6 +2233,8 @@ int QTableView::sizeHintForRow(int row) const
return -1;
ensurePolished();
+ const int maximumProcessCols = d->verticalHeader->resizeContentsPrecision();
+
int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
@@ -2195,27 +2245,55 @@ int QTableView::sizeHintForRow(int row) const
int hint = 0;
QModelIndex index;
- for (int column = left; column <= right; ++column) {
+ int columnsProcessed = 0;
+ int column = left;
+ for (; column <= right; ++column) {
int logicalColumn = d->horizontalHeader->logicalIndex(column);
if (d->horizontalHeader->isSectionHidden(logicalColumn))
continue;
index = d->model->index(row, logicalColumn, d->root);
- if (d->wrapItemText) {// for wrapping boundaries
- option.rect.setY(rowViewportPosition(index.row()));
- option.rect.setHeight(rowHeight(index.row()));
- option.rect.setX(columnViewportPosition(index.column()));
- option.rect.setWidth(columnWidth(index.column()));
- }
+ hint = d->heightHintForIndex(index, hint, option);
+
+ ++columnsProcessed;
+ if (columnsProcessed == maximumProcessCols)
+ break;
+ }
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- hint = qMax(hint, editor->sizeHint().height());
- int min = editor->minimumSize().height();
- int max = editor->maximumSize().height();
- hint = qBound(min, hint, max);
+ int actualRight = d->model->columnCount(d->root) - 1;
+ int idxLeft = left;
+ int idxRight = column - 1;
+
+ if (maximumProcessCols == 0)
+ columnsProcessed = 0; // skip the while loop
+
+ while (columnsProcessed != maximumProcessCols && (idxLeft > 0 || idxRight < actualRight)) {
+ int logicalIdx = -1;
+
+ if ((columnsProcessed % 2 && idxLeft > 0) || idxRight == actualRight) {
+ while (idxLeft > 0) {
+ --idxLeft;
+ int logcol = d->horizontalHeader->logicalIndex(idxLeft);
+ if (d->horizontalHeader->isSectionHidden(logcol))
+ continue;
+ logicalIdx = logcol;
+ break;
+ }
+ } else {
+ while (idxRight < actualRight) {
+ ++idxRight;
+ int logcol = d->horizontalHeader->logicalIndex(idxRight);
+ if (d->horizontalHeader->isSectionHidden(logcol))
+ continue;
+ logicalIdx = logcol;
+ break;
+ }
}
+ if (logicalIdx < 0)
+ continue;
- hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).height());
+ index = d->model->index(row, logicalIdx, d->root);
+ hint = d->heightHintForIndex(index, hint, option);
+ ++columnsProcessed;
}
return d->showGrid ? hint + 1 : hint;
@@ -2234,7 +2312,7 @@ int QTableView::sizeHintForRow(int row) const
required by either the horizontal header or the item delegate, the larger
width will be used instead.
- \sa QWidget::sizeHint, horizontalHeader()
+ \sa QWidget::sizeHint, horizontalHeader(), QHeaderView::resizeContentsPrecision()
*/
int QTableView::sizeHintForColumn(int column) const
{
@@ -2244,6 +2322,7 @@ int QTableView::sizeHintForColumn(int column) const
return -1;
ensurePolished();
+ const int maximumProcessRows = d->horizontalHeader->resizeContentsPrecision();
int top = qMax(0, d->verticalHeader->visualIndexAt(0));
int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
@@ -2253,22 +2332,56 @@ int QTableView::sizeHintForColumn(int column) const
QStyleOptionViewItem option = d->viewOptions();
int hint = 0;
+ int rowsProcessed = 0;
QModelIndex index;
- for (int row = top; row <= bottom; ++row) {
+ int row = top;
+ for (; row <= bottom; ++row) {
int logicalRow = d->verticalHeader->logicalIndex(row);
if (d->verticalHeader->isSectionHidden(logicalRow))
continue;
index = d->model->index(logicalRow, column, d->root);
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- hint = qMax(hint, editor->sizeHint().width());
- int min = editor->minimumSize().width();
- int max = editor->maximumSize().width();
- hint = qBound(min, hint, max);
+ hint = d->widthHintForIndex(index, hint, option);
+ ++rowsProcessed;
+ if (rowsProcessed == maximumProcessRows)
+ break;
+ }
+
+ int actualBottom = d->model->rowCount(d->root) - 1;
+ int idxTop = top;
+ int idxBottom = row - 1;
+
+ if (maximumProcessRows == 0)
+ rowsProcessed = 0; // skip the while loop
+
+ while (rowsProcessed != maximumProcessRows && (idxTop > 0 || idxBottom < actualBottom)) {
+ int logicalIdx = -1;
+
+ if ((rowsProcessed % 2 && idxTop > 0) || idxBottom == actualBottom) {
+ while (idxTop > 0) {
+ --idxTop;
+ int logrow = d->verticalHeader->logicalIndex(idxTop);
+ if (d->verticalHeader->isSectionHidden(logrow))
+ continue;
+ logicalIdx = logrow;
+ break;
+ }
+ } else {
+ while (idxBottom < actualBottom) {
+ ++idxBottom;
+ int logrow = d->verticalHeader->logicalIndex(idxBottom);
+ if (d->verticalHeader->isSectionHidden(logrow))
+ continue;
+ logicalIdx = logrow;
+ break;
+ }
}
+ if (logicalIdx < 0)
+ continue;
- hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).width());
+ index = d->model->index(logicalIdx, column, d->root);
+ hint = d->widthHintForIndex(index, hint, option);
+ ++rowsProcessed;
}
return d->showGrid ? hint + 1 : hint;
@@ -2934,6 +3047,8 @@ void QTableView::showColumn(int column)
/*!
Resizes the given \a row based on the size hints of the delegate
used to render each item in the row.
+
+ \sa resizeRowsToContents(), sizeHintForRow(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeRowToContents(int row)
{
@@ -2946,6 +3061,8 @@ void QTableView::resizeRowToContents(int row)
/*!
Resizes all rows based on the size hints of the delegate
used to render each item in the rows.
+
+ \sa resizeRowToContents(), sizeHintForRow(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeRowsToContents()
{
@@ -2959,6 +3076,8 @@ void QTableView::resizeRowsToContents()
\note Only visible columns will be resized. Reimplement sizeHintForColumn()
to resize hidden columns as well.
+
+ \sa resizeColumnsToContents(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeColumnToContents(int column)
{
@@ -2971,6 +3090,8 @@ void QTableView::resizeColumnToContents(int column)
/*!
Resizes all columns based on the size hints of the delegate
used to render each item in the columns.
+
+ \sa resizeColumnToContents(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeColumnsToContents()
{
diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h
index 824348dbe8..db956480d6 100644
--- a/src/widgets/itemviews/qtableview.h
+++ b/src/widgets/itemviews/qtableview.h
@@ -118,6 +118,8 @@ public:
void sortByColumn(int column, Qt::SortOrder order);
+ QSize viewportSizeHint() const;
+
public Q_SLOTS:
void selectRow(int row);
void selectColumn(int column);
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index 923beec253..d36dcd2c3a 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -181,6 +181,8 @@ public:
const QStyleOptionViewItem &option, QBitArray *drawn,
int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn);
void drawCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index);
+ int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const;
+ int heightHintForIndex(const QModelIndex &index, int hint, QStyleOptionViewItem &option) const;
bool showGrid;
Qt::PenStyle gridStyle;
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index d56314b23d..f15124605f 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -510,7 +510,7 @@ void QTableModel::sort(int column, Qt::SortOrder order)
}
LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- qStableSort(sortable.begin(), sortable.end(), compare);
+ std::stable_sort(sortable.begin(), sortable.end(), compare);
QVector<QTableWidgetItem*> sorted_table(tableItems.count());
QModelIndexList from;
@@ -558,7 +558,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
}
LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- qStableSort(sorting.begin(), sorting.end(), compare);
+ std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes = persistentIndexList();
QModelIndexList newPersistentIndexes = oldPersistentIndexes;
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 6aefbb5367..b5f1b12365 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -61,6 +61,8 @@
#include <private/qtreeview_p.h>
#include <private/qheaderview_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
/*!
@@ -335,6 +337,7 @@ void QTreeView::setHeader(QHeaderView *header)
this, SLOT(updateGeometries()));
setSortingEnabled(d->sortingEnabled);
+ d->updateGeometry();
}
/*!
@@ -952,6 +955,36 @@ bool QTreeView::wordWrap() const
return d->wrapItemText;
}
+/*!
+ \since 5.2
+
+ This specifies that the tree structure should be placed at logical index \a index.
+ If \index is set to -1 then the tree will always follow visual index 0.
+
+ \sa treePosition(), QHeaderView::swapSections(), QHeaderView::moveSection()
+*/
+
+void QTreeView::setTreePosition(int index)
+{
+ Q_D(QTreeView);
+ d->treePosition = index;
+ update();
+}
+
+/*!
+ \since 5.2
+
+ Return the logical index the tree is set on. If the return value is -1 then the
+ tree is placed on the visual index 0.
+
+ \sa setTreePosition()
+*/
+
+int QTreeView::treePosition() const
+{
+ Q_D(const QTreeView);
+ return d->treePosition;
+}
/*!
\reimp
@@ -1067,7 +1100,7 @@ QRect QTreeView::visualRect(const QModelIndex &index) const
int x = (spanning ? 0 : columnViewportPosition(index.column()));
int w = (spanning ? d->header->length() : columnWidth(index.column()));
// handle indentation
- if (index.column() == 0) {
+ if (d->isTreePosition(index.column())) {
int i = d->indentationForItem(vi);
w -= i;
if (!isRightToLeft())
@@ -1284,6 +1317,14 @@ void QTreeView::paintEvent(QPaintEvent *event)
}
}
+int QTreeViewPrivate::logicalIndexForTree() const
+{
+ int index = treePosition;
+ if (index < 0)
+ index = header->logicalIndex(0);
+ return index;
+}
+
void QTreeViewPrivate::paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItem *option, int y, int bottom) const
{
Q_Q(const QTreeView);
@@ -1516,7 +1557,7 @@ void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<
if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1)
|| (headerSection == 0 && nextLogicalSection == -1) || spanning)
pos = QStyleOptionViewItem::OnlyOne;
- else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1))
+ else if (isTreePosition(headerSection) || (nextLogicalSection != 0 && prevLogicalSection == -1))
pos = QStyleOptionViewItem::Beginning;
else if (nextLogicalSection == 0 || nextLogicalSection == -1)
pos = QStyleOptionViewItem::End;
@@ -1526,6 +1567,23 @@ void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<
}
}
+/*!
+ \internal
+ Get sizeHint width for single index (providing existing hint and style option) and index in viewIndex i.
+*/
+int QTreeViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const
+{
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+ int min = editor->minimumSize().width();
+ int max = editor->maximumSize().width();
+ hint = qBound(min, hint, max);
+ }
+ int xhint = delegateForIndex(index)->sizeHint(option, index).width();
+ hint = qMax(hint, xhint + (isTreePosition(index.column()) ? indentationForItem(i) : 0));
+ return hint;
+}
/*!
Draws the row in the tree view that contains the model item \a index,
@@ -1668,7 +1726,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
alternate row color was provided by the view. For backward compatibility,
this is now delegated to the style using PE_PanelViewItemRow which
does the appropriate fill */
- if (headerSection == 0) {
+ if (d->isTreePosition(headerSection)) {
const int i = d->indentationForItem(d->current);
QRect branches(reverse ? position + width - i : position, y, i, height);
const bool setClipRect = branches.width() > width;
@@ -2123,10 +2181,10 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
if (!current.isValid()) {
int i = d->below(-1);
int c = 0;
- while (c < d->header->count() && d->header->isSectionHidden(c))
+ while (c < d->header->count() && d->header->isSectionHidden(d->header->logicalIndex(c)))
++c;
if (i < d->viewItems.count() && c < d->header->count()) {
- return d->modelIndex(i, c);
+ return d->modelIndex(i, d->header->logicalIndex(c));
}
return QModelIndex();
}
@@ -2400,16 +2458,11 @@ void QTreeView::scrollContentsBy(int dx, int dy)
dx = isRightToLeft() ? -dx : dx;
if (dx) {
+ int oldOffset = d->header->offset();
+ d->header->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode());
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->header->offset();
- if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum())
- d->header->setOffsetToLastSection();
- else
- d->header->setOffsetToSectionPosition(horizontalScrollBar()->value());
int newOffset = d->header->offset();
dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
- } else {
- d->header->setOffset(horizontalScrollBar()->value());
}
}
@@ -2552,7 +2605,7 @@ void QTreeView::columnCountChanged(int oldCount, int newCount)
/*!
Resizes the \a column given to the size of its contents.
- \sa columnWidth(), setColumnWidth()
+ \sa columnWidth(), setColumnWidth(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()
*/
void QTreeView::resizeColumnToContents(int column)
{
@@ -2619,6 +2672,35 @@ void QTreeView::selectAll()
}
/*!
+ \reimp
+*/
+QSize QTreeView::viewportSizeHint() const
+{
+ Q_D(const QTreeView);
+ d->executePostedLayout(); // Make sure that viewItems are up to date.
+
+ if (d->viewItems.size() == 0)
+ return QAbstractItemView::viewportSizeHint();
+
+ // Get rect for last item
+ const QRect deepestRect = visualRect(d->viewItems.last().index);
+
+ if (!deepestRect.isValid())
+ return QAbstractItemView::viewportSizeHint();
+
+ QSize result = QSize(d->header->length(), deepestRect.bottom() + 1);
+
+ // add size for header
+ result += QSize(0, d->header->isVisible() ? d->header->height() : 0);
+
+ // add size for scrollbars
+ result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,
+ horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);
+
+ return result;
+}
+
+/*!
\since 4.2
Expands all expandable items.
@@ -2740,7 +2822,6 @@ void QTreeView::updateGeometries()
QRect vg = d->viewport->geometry();
QRect geometryRect(vg.left(), vg.top() - hint.height(), vg.width(), hint.height());
d->header->setGeometry(geometryRect);
- //d->header->setOffset(horizontalScrollBar()->value()); // ### bug ???
QMetaObject::invokeMethod(d->header, "updateGeometries");
d->updateScrollBars();
d->geometryRecursionBlock = false;
@@ -2760,7 +2841,7 @@ void QTreeView::updateGeometries()
if a larger column width is required by either the view's header or
the item delegate, that width will be used instead.
- \sa QWidget::sizeHint, header()
+ \sa QWidget::sizeHint, header(), QHeaderView::resizeContentsPrecision()
*/
int QTreeView::sizeHintForColumn(int column) const
{
@@ -2773,28 +2854,58 @@ int QTreeView::sizeHintForColumn(int column) const
QStyleOptionViewItem option = d->viewOptions();
const QVector<QTreeViewItem> viewItems = d->viewItems;
- int start = 0;
- int end = viewItems.count();
- if(end > 1000) { //if we have too many item this function would be too slow.
- //we get a good approximation by only iterate over 1000 items.
- start = qMax(0, d->firstVisibleItem() - 100);
- end = qMin(end, start + 900);
- }
+ const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever.
+
+ int offset = 0;
+ int start = d->firstVisibleItem(&offset);
+ int end = d->lastVisibleItem(start, offset);
- for (int i = start; i < end; ++i) {
+ int rowsProcessed = 0;
+
+ for (int i = start; i <= end; ++i) {
if (viewItems.at(i).spanning)
continue; // we have no good size hint
QModelIndex index = viewItems.at(i).index;
index = index.sibling(index.row(), column);
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- w = qMax(w, editor->sizeHint().width());
- int min = editor->minimumSize().width();
- int max = editor->maximumSize().width();
- w = qBound(min, w, max);
+ w = d->widthHintForIndex(index, w, option, i);
+ ++rowsProcessed;
+ if (rowsProcessed == maximumProcessRows)
+ break;
+ }
+
+ --end;
+ int actualBottom = viewItems.size() - 1;
+
+ if (maximumProcessRows == 0)
+ rowsProcessed = 0; // skip the while loop
+
+ while (rowsProcessed != maximumProcessRows && (start > 0 || end < actualBottom)) {
+ int idx = -1;
+
+ if ((rowsProcessed % 2 && start > 0) || end == actualBottom) {
+ while (start > 0) {
+ --start;
+ if (viewItems.at(start).spanning)
+ continue;
+ idx = start;
+ break;
+ }
+ } else {
+ while (end < actualBottom) {
+ ++end;
+ if (viewItems.at(end).spanning)
+ continue;
+ idx = end;
+ break;
+ }
}
- int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
- w = qMax(w, hint + (column == 0 ? d->indentationForItem(i) : 0));
+ if (idx < 0)
+ continue;
+
+ QModelIndex index = viewItems.at(idx).index;
+ index = index.sibling(index.row(), column);
+ w = d->widthHintForIndex(index, w, option, idx);
+ ++rowsProcessed;
}
return w;
}
@@ -2915,6 +3026,7 @@ void QTreeViewPrivate::initialize()
header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter);
q->setHeader(header);
#ifndef QT_NO_ANIMATION
+ animationsEnabled = q->style()->styleHint(QStyle::SH_Widget_Animate, 0, q);
QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
#endif //QT_NO_ANIMATION
}
@@ -3314,7 +3426,7 @@ int QTreeViewPrivate::coordinateForItem(int item) const
if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
if (uniformRowHeights)
return (item * defaultItemHeight) - vbar->value();
- // ### optimize (spans or caching)
+ // ### optimize (maybe do like QHeaderView by letting items have startposition)
int y = 0;
for (int i = 0; i < viewItems.count(); ++i) {
if (i == item)
@@ -3481,7 +3593,7 @@ int QTreeViewPrivate::firstVisibleItem(int *offset) const
*offset = -(value % defaultItemHeight);
return value / defaultItemHeight;
}
- int y = 0; // ### optimize (use spans ?)
+ int y = 0; // ### (maybe do like QHeaderView by letting items have startposition)
for (int i = 0; i < viewItems.count(); ++i) {
y += itemHeight(i); // the height value is cached
if (y > value) {
@@ -3493,6 +3605,21 @@ int QTreeViewPrivate::firstVisibleItem(int *offset) const
return -1;
}
+int QTreeViewPrivate::lastVisibleItem(int firstVisual, int offset) const
+{
+ if (firstVisual < 0 || offset < 0)
+ firstVisual = firstVisibleItem(&offset);
+ int y = - offset;
+ int value = viewport->height();
+
+ for (int i = firstVisual; i < viewItems.count(); ++i) {
+ y += itemHeight(i); // the height value is cached
+ if (y > value)
+ return i;
+ }
+ return viewItems.size() - 1;
+}
+
int QTreeViewPrivate::columnAt(int x) const
{
return header->logicalIndexAt(x);
@@ -3535,13 +3662,13 @@ void QTreeViewPrivate::updateScrollBars()
int contentsHeight = 0;
if (uniformRowHeights) {
contentsHeight = defaultItemHeight * viewItems.count();
- } else { // ### optimize (spans or caching)
+ } else { // ### (maybe do like QHeaderView by letting items have startposition)
for (int i = 0; i < viewItems.count(); ++i)
contentsHeight += itemHeight(i);
}
vbar->setRange(0, contentsHeight - viewportSize.height());
vbar->setPageStep(viewportSize.height());
- vbar->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
+ // here we do not want to overwrite (a possible user set) single step
}
const int columnCount = header->count();
@@ -3567,7 +3694,7 @@ void QTreeViewPrivate::updateScrollBars()
viewportSize = maxSize;
hbar->setPageStep(viewportSize.width());
hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
- hbar->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
+ // here we do not want to overwrite (a possible user set) single step
}
}
@@ -3576,7 +3703,7 @@ int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
executePostedLayout();
int x = pos.x();
int column = header->logicalIndexAt(x);
- if (column != 0)
+ if (!isTreePosition(column))
return -1; // no logical index at x
int viewItemIndex = itemAtCoordinate(pos.y());
@@ -3598,8 +3725,8 @@ QRect QTreeViewPrivate::itemDecorationRect(const QModelIndex &index) const
return QRect();
int itemIndentation = indentationForItem(viewItemIndex);
- int position = header->sectionViewportPosition(0);
- int size = header->sectionSize(0);
+ int position = header->sectionViewportPosition(logicalIndexForTree());
+ int size = header->sectionSize(logicalIndexForTree());
QRect rect;
if (q->isRightToLeft())
@@ -3633,7 +3760,7 @@ QList<QPair<int, int> > QTreeViewPrivate::columnRanges(const QModelIndex &topInd
}
}
//let's sort the list
- qSort(logicalIndexes.begin(), logicalIndexes.end());
+ std::sort(logicalIndexes.begin(), logicalIndexes.end());
QList<QPair<int, int> > ret;
QPair<int, int> current;
diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h
index 73f11f1a48..d9c6cd9269 100644
--- a/src/widgets/itemviews/qtreeview.h
+++ b/src/widgets/itemviews/qtreeview.h
@@ -128,6 +128,9 @@ public:
void setWordWrap(bool on);
bool wordWrap() const;
+ void setTreePosition(int logicalIndex);
+ int treePosition() const;
+
void keyboardSearch(const QString &search);
QRect visualRect(const QModelIndex &index) const;
@@ -144,6 +147,8 @@ public:
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
void selectAll();
+ QSize viewportSizeHint() const;
+
Q_SIGNALS:
void expanded(const QModelIndex &index);
void collapsed(const QModelIndex &index);
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
index 90e83cb58c..89de435606 100644
--- a/src/widgets/itemviews/qtreeview_p.h
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -91,10 +91,16 @@ public:
expandsOnDoubleClick(true),
allColumnsShowFocus(false), current(0), spanning(false),
animationsEnabled(false), columnResizeTimerID(0),
- autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false) {}
+ autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false),
+ treePosition(0) {}
~QTreeViewPrivate() {}
void initialize();
+ int logicalIndexForTree() const;
+ inline bool isTreePosition(int logicalIndex) const
+ {
+ return logicalIndex == logicalIndexForTree();
+ }
QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
void adjustViewOptionsForIndex(QStyleOptionViewItem *option, const QModelIndex &current) const;
@@ -148,6 +154,7 @@ public:
#endif
int firstVisibleItem(int *offset = 0) const;
+ int lastVisibleItem(int firstVisual = -1, int offset = -1) const;
int columnAt(int x) const;
bool hasVisibleChildren( const QModelIndex& parent) const;
@@ -171,7 +178,7 @@ public:
// logicalIndices: vector of currently visibly logical indices
// itemPositions: vector of view item positions (beginning/middle/end/onlyone)
void calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItem::ViewItemPosition> *itemPositions, int left, int right) const;
-
+ int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const;
QHeaderView *header;
int indent;
@@ -251,6 +258,9 @@ public:
// If we should clean the set
bool hasRemovedItems;
+
+ // tree position
+ int treePosition;
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index f72abd20ab..f098236d5c 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -614,7 +614,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
}
LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- qStableSort(sorting.begin(), sorting.end(), compare);
+ std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes;
QModelIndexList newPersistentIndexes;
@@ -623,7 +623,13 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
for (int i = 0; i < count; ++i) {
int oldRow = sorting.at(i).second;
+
+ int tmpitepos = lit - lst.begin();
QTreeWidgetItem *item = lst.takeAt(oldRow);
+ if (tmpitepos > lst.size())
+ --tmpitepos;
+ lit = lst.begin() + tmpitepos;
+
lit = sortedInsertionIterator(lit, lst.end(), order, item);
int newRow = qMax(lit - lst.begin(), 0);
@@ -848,7 +854,7 @@ void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortO
// do the sorting
LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- qStableSort(sorting.begin(), sorting.end(), compare);
+ std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList fromList;
QModelIndexList toList;
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index b918bdb9e9..af3d134a5a 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -1852,8 +1852,11 @@ bool QApplication::event(QEvent *e)
if (showToolTip) {
QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos);
QApplication::sendEvent(d->toolTipWidget, &e);
- if (e.isAccepted())
- d->toolTipFallAsleep.start(2000, this);
+ if (e.isAccepted()) {
+ QStyle *s = d->toolTipWidget->style();
+ int sleepDelay = s->styleHint(QStyle::SH_ToolTip_FallAsleepDelay, 0, d->toolTipWidget, 0);
+ d->toolTipFallAsleep.start(sleepDelay, this);
+ }
}
}
} else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
@@ -2949,12 +2952,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint relpos = mouse->pos();
if (e->spontaneous()) {
-
- if (e->type() == QEvent::MouseButtonPress) {
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
- Qt::ClickFocus,
- Qt::MouseFocusReason);
- }
+ if (e->type() != QEvent::MouseMove)
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos);
// ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
// like Mac OS X (probably others too), can optimize their views by not
@@ -2967,7 +2966,9 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->toolTipWidget = w;
d->toolTipPos = relpos;
d->toolTipGlobalPos = mouse->globalPos();
- d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
+ QStyle *s = d->toolTipWidget->style();
+ int wakeDelay = s->styleHint(QStyle::SH_ToolTip_WakeUpDelay, 0, d->toolTipWidget, 0);
+ d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive() ? 20 : wakeDelay, this);
}
}
@@ -3042,11 +3043,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint relpos = wheel->pos();
bool eventAccepted = wheel->isAccepted();
- if (e->spontaneous()) {
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
- Qt::WheelFocus,
- Qt::MouseFocusReason);
- }
+ if (e->spontaneous())
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos);
while (w) {
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
@@ -3234,6 +3232,11 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
const bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+ if (e->type() != QEvent::TouchUpdate && acceptTouchEvents && e->spontaneous()) {
+ const QPoint localPos = touchEvent->touchPoints()[0].pos().toPoint();
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget, e, localPos);
+ }
+
touchEvent->setTarget(widget);
touchEvent->setAccepted(acceptTouchEvents);
@@ -3251,16 +3254,16 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QWidget *widget = static_cast<QWidget *>(receiver);
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
bool eventAccepted = touchEvent->isAccepted();
- if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
- // give the widget focus if the focus policy allows it
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
- Qt::ClickFocus,
- Qt::MouseFocusReason);
+ bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+
+ if (acceptTouchEvents && e->spontaneous()) {
+ const QPoint localPos = touchEvent->touchPoints()[0].pos().toPoint();
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget, e, localPos);
}
while (widget) {
// first, try to deliver the touch event
- bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+ acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
touchEvent->setTarget(widget);
touchEvent->setAccepted(acceptTouchEvents);
QPointer<QWidget> p = widget;
@@ -3725,20 +3728,40 @@ bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
return QGuiApplication::sendSpontaneousEvent(receiver, event);
}
-
-void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
- Qt::FocusPolicy focusPolicy,
- Qt::FocusReason focusReason)
+void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, QEvent *event, QPoint localPos)
{
+ const bool setFocusOnRelease = QGuiApplication::styleHints()->setFocusOnTouchRelease();
+ Qt::FocusPolicy focusPolicy = Qt::ClickFocus;
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::TouchBegin:
+ if (setFocusOnRelease)
+ return;
+ break;
+ case QEvent::MouseButtonRelease:
+ case QEvent::TouchEnd:
+ if (!setFocusOnRelease)
+ return;
+ break;
+ case QEvent::Wheel:
+ focusPolicy = Qt::WheelFocus;
+ break;
+ default:
+ return;
+ }
+
QWidget *focusWidget = widget;
while (focusWidget) {
if (focusWidget->isEnabled()
+ && focusWidget->rect().contains(localPos)
&& QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
- focusWidget->setFocus(focusReason);
+ focusWidget->setFocus(Qt::MouseFocusReason);
break;
}
if (focusWidget->isWindow())
break;
+ localPos += focusWidget->pos();
focusWidget = focusWidget->parentWidget();
}
}
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 87cf259ba5..29c6902c78 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -294,9 +294,7 @@ public:
private:
static QApplicationPrivate *self;
- static void giveFocusAccordingToFocusPolicy(QWidget *w,
- Qt::FocusPolicy focusPolicy,
- Qt::FocusReason focusReason);
+ static void giveFocusAccordingToFocusPolicy(QWidget *w, QEvent *event, QPoint localPos);
static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy);
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 852b6b9697..0fc065e74b 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -198,7 +198,6 @@ void QApplicationPrivate::closePopup(QWidget *popup)
// mouse release event or inside
qt_replay_popup_mouse_event = false;
} else { // mouse press event
- QGuiApplicationPrivate::mousePressTime -= 10000; // avoid double click
qt_replay_popup_mouse_event = true;
}
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index a65c34adf5..8541dd984d 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -1443,7 +1443,7 @@ QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy)
policy.bits.hfw << 8 | // [8]
policy.bits.ctype << 9 | // [9, 13]
policy.bits.wfh << 14 | // [14]
- //policy.bits.padding << 15 | // [15]
+ policy.bits.retainSizeWhenHidden << 15 | // [15]
policy.bits.verStretch << 16 | // [16, 23]
policy.bits.horStretch << 24); // [24, 31]
return stream << data;
@@ -1468,7 +1468,7 @@ QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy)
policy.bits.hfw = VALUE_OF_BITS(data, 8, 1);
policy.bits.ctype = VALUE_OF_BITS(data, 9, 5);
policy.bits.wfh = VALUE_OF_BITS(data, 14, 1);
- policy.bits.padding = 0;
+ policy.bits.retainSizeWhenHidden = VALUE_OF_BITS(data, 15, 1);
policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8);
policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8);
return stream;
diff --git a/src/widgets/kernel/qlayoutengine.cpp b/src/widgets/kernel/qlayoutengine.cpp
index 8800da33b4..fe27edd35d 100644
--- a/src/widgets/kernel/qlayoutengine.cpp
+++ b/src/widgets/kernel/qlayoutengine.cpp
@@ -46,10 +46,10 @@
#include "qwidget.h"
#include <qlist.h>
-#include <qalgorithms.h>
-
#include <qdebug.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
//#define QLAYOUT_EXTRA_DEBUG
@@ -83,9 +83,7 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
int cMax = 0;
int sumStretch = 0;
int sumSpacing = 0;
-
- bool wannaGrow = false; // anyone who really wants to grow?
- // bool canShrink = false; // anyone who could be persuaded to shrink?
+ int expandingCount = 0;
bool allEmptyNonstretch = true;
int pendingSpacing = -1;
@@ -111,8 +109,9 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
}
pendingSpacing = data->effectiveSpacer(spacer);
}
- wannaGrow = wannaGrow || data->expansive || data->stretch > 0;
- allEmptyNonstretch = allEmptyNonstretch && !wannaGrow && data->empty;
+ if (data->expansive)
+ expandingCount++;
+ allEmptyNonstretch = allEmptyNonstretch && data->empty && !data->expansive && data->stretch <= 0;
}
int extraspace = 0;
@@ -135,7 +134,7 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
for (i = start; i < start + count; i++)
list << chain.at(i).minimumSize;
- qSort(list);
+ std::sort(list.begin(), list.end());
int space_left = space - sumSpacing;
@@ -233,13 +232,14 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
QLayoutStruct *data = &chain[i];
if (!data->done
&& (data->maximumSize <= data->smartSizeHint()
- || (wannaGrow && !data->expansive && data->stretch == 0)
|| (!allEmptyNonstretch && data->empty &&
!data->expansive && data->stretch == 0))) {
data->size = data->smartSizeHint();
data->done = true;
space_left -= data->size;
sumStretch -= data->stretch;
+ if (data->expansive)
+ expandingCount--;
n--;
}
}
@@ -265,10 +265,13 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
if (data->done)
continue;
extraspace = 0;
- if (sumStretch <= 0)
- fp_w += fp_space / n;
- else
+ if (sumStretch > 0) {
fp_w += (fp_space * data->stretch) / sumStretch;
+ } else if (expandingCount > 0) {
+ fp_w += (fp_space * (data->expansive ? 1 : 0)) / expandingCount;
+ } else {
+ fp_w += fp_space * 1 / n;
+ }
int w = fRound(fp_w);
data->size = w;
fp_w -= toFixed(w); // give the difference to the next
@@ -287,6 +290,8 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
data->done = true;
space_left -= data->smartSizeHint();
sumStretch -= data->stretch;
+ if (data->expansive)
+ expandingCount--;
n--;
}
}
@@ -300,6 +305,8 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
data->done = true;
space_left -= data->maximumSize;
sumStretch -= data->stretch;
+ if (data->expansive)
+ expandingCount--;
n--;
}
}
diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp
index 223bcf1d9b..a99ea77ce2 100644
--- a/src/widgets/kernel/qlayoutitem.cpp
+++ b/src/widgets/kernel/qlayoutitem.cpp
@@ -682,7 +682,7 @@ bool QSpacerItem::isEmpty() const
*/
bool QWidgetItem::isEmpty() const
{
- return wid->isHidden() || wid->isWindow();
+ return (wid->isHidden() && !wid->sizePolicy().retainSizeWhenHidden()) || wid->isWindow();
}
/*!
diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h
index 2fe85cbe0c..9c6d67410a 100644
--- a/src/widgets/kernel/qsizepolicy.h
+++ b/src/widgets/kernel/qsizepolicy.h
@@ -131,6 +131,9 @@ public:
void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
+ bool retainSizeWhenHidden() const { return bits.retainSizeWhenHidden; }
+ void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; }
+
void transpose();
@@ -150,7 +153,7 @@ private:
quint32 ctype : 5;
quint32 hfw : 1;
quint32 wfh : 1;
- quint32 padding : 1; // feel free to use
+ quint32 retainSizeWhenHidden : 1;
} bits;
quint32 data;
};
diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc
index 6af694d999..2c088113e1 100644
--- a/src/widgets/kernel/qsizepolicy.qdoc
+++ b/src/widgets/kernel/qsizepolicy.qdoc
@@ -341,6 +341,23 @@
*/
/*!
+ \fn void QSizePolicy::retainSizeWhenHidden() const
+
+ Returns if the layout should retain the widgets size when it is hidden. This is by default false.
+
+ \sa setRetainSizeWhenHidden()
+*/
+
+/*!
+ \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize)
+
+ Set if a layout should retain the widgets size when it is hidden.
+ If \a retainSize is true the layout will not be changed by hiding the widget.
+
+ \sa retainSizeWhenHidden()
+*/
+
+/*!
\enum QSizePolicy::ControlType
\since 4.3
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 864ed6a555..8399f94976 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -120,7 +120,7 @@ class QTipLabel : public QLabel
{
Q_OBJECT
public:
- QTipLabel(const QString &text, QWidget *w);
+ QTipLabel(const QString &text, QWidget *w, int msecDisplayTime);
~QTipLabel();
static QTipLabel *instance;
@@ -130,11 +130,11 @@ public:
bool fadingOut;
- void reuseTip(const QString &text);
+ void reuseTip(const QString &text, int msecDisplayTime);
void hideTip();
void hideTipImmediately();
void setTipRect(QWidget *w, const QRect &r);
- void restartExpireTimer();
+ void restartExpireTimer(int msecDisplayTime);
bool tipChanged(const QPoint &pos, const QString &text, QObject *o);
void placeTip(const QPoint &pos, QWidget *w);
@@ -166,7 +166,7 @@ private:
QTipLabel *QTipLabel::instance = 0;
-QTipLabel::QTipLabel(const QString &text, QWidget *w)
+QTipLabel::QTipLabel(const QString &text, QWidget *w, int msecDisplayTime)
#ifndef QT_NO_STYLE_STYLESHEET
: QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), styleSheetParent(0), widget(0)
#else
@@ -187,17 +187,19 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w)
setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
setMouseTracking(true);
fadingOut = false;
- reuseTip(text);
+ reuseTip(text, msecDisplayTime);
}
-void QTipLabel::restartExpireTimer()
+void QTipLabel::restartExpireTimer(int msecDisplayTime)
{
int time = 10000 + 40 * qMax(0, text().length()-100);
+ if (msecDisplayTime > 0)
+ time = msecDisplayTime;
expireTimer.start(time, this);
hideTimer.stop();
}
-void QTipLabel::reuseTip(const QString &text)
+void QTipLabel::reuseTip(const QString &text, int msecDisplayTime)
{
#ifndef QT_NO_STYLE_STYLESHEET
if (styleSheetParent){
@@ -215,7 +217,7 @@ void QTipLabel::reuseTip(const QString &text)
if (fm.descent() == 2 && fm.ascent() >= 11)
++extra.rheight();
resize(sizeHint() + extra);
- restartExpireTimer();
+ restartExpireTimer(msecDisplayTime);
}
void QTipLabel::paintEvent(QPaintEvent *ev)
@@ -440,6 +442,18 @@ bool QTipLabel::tipChanged(const QPoint &pos, const QString &text, QObject *o)
void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect)
{
+ showText(pos, text, w, rect, -1);
+}
+
+/*!
+ \since 5.2
+ \overload
+ This is similar to QToolTip::showText(\a pos, \a text, \a w, \a rect) but with an extra parameter \a msecDisplayTime
+ that specifies how long the tool tip will be displayed, in milliseconds.
+*/
+
+void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime)
+{
if (QTipLabel::instance && QTipLabel::instance->isVisible()){ // a tip does already exist
if (text.isEmpty()){ // empty text means hide current tip
QTipLabel::instance->hideTip();
@@ -452,7 +466,7 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
if (w)
localPos = w->mapFromGlobal(pos);
if (QTipLabel::instance->tipChanged(localPos, text, w)){
- QTipLabel::instance->reuseTip(text);
+ QTipLabel::instance->reuseTip(text, msecDisplayTime);
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
}
@@ -462,11 +476,11 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
if (!text.isEmpty()){ // no tip can be reused, create new tip:
#ifndef Q_WS_WIN
- new QTipLabel(text, w); // sets QTipLabel::instance to itself
+ new QTipLabel(text, w, msecDisplayTime); // sets QTipLabel::instance to itself
#else
// On windows, we can't use the widget as parent otherwise the window will be
// raised when the tooltip will be shown
- new QTipLabel(text, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)));
+ new QTipLabel(text, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)), msecDisplayTime);
#endif
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
diff --git a/src/widgets/kernel/qtooltip.h b/src/widgets/kernel/qtooltip.h
index 25b138b855..ccde405342 100644
--- a/src/widgets/kernel/qtooltip.h
+++ b/src/widgets/kernel/qtooltip.h
@@ -53,8 +53,10 @@ class Q_WIDGETS_EXPORT QToolTip
{
QToolTip() Q_DECL_EQ_DELETE;
public:
+ // ### Qt 6 - merge the three showText functions below
static void showText(const QPoint &pos, const QString &text, QWidget *w = 0);
static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect);
+ static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecShowTime);
static inline void hideText() { showText(QPoint(), QString()); }
static bool isVisible();
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 49d64c5cd8..5532b04b22 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -245,6 +245,9 @@ QWidgetPrivate::QWidgetPrivate(int version)
#if !defined(QT_NO_IM)
, imHints(Qt::ImhNone)
#endif
+#ifndef QT_NO_TOOLTIP
+ , toolTipDuration(-1)
+#endif
, inheritedFontResolveMask(0)
, inheritedPaletteResolveMask(0)
, leftmargin(0)
@@ -261,6 +264,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, bg_role(QPalette::NoRole)
, dirtyOpaqueChildren(1)
, isOpaque(0)
+ , retainSizeWhenHiddenChanged(0)
, inDirtyList(0)
, isScrolled(0)
, isMoved(0)
@@ -7264,10 +7268,19 @@ void QWidget::setVisible(bool visible)
create();
}
-#if defined(Q_WS_X11)
- if (windowType() == Qt::Window)
- QApplicationPrivate::applyX11SpecificCommandLineArguments(this);
-#endif
+ // Handling of the -qwindowgeometry, -geometry command line arguments
+ if (windowType() == Qt::Window && windowHandle()) {
+ static bool done = false;
+ if (!done) {
+ done = true;
+ const QRect oldGeometry = frameGeometry();
+ const QRect geometry = QGuiApplicationPrivate::applyWindowGeometrySpecification(oldGeometry, windowHandle());
+ if (oldGeometry.size() != geometry.size())
+ resize(geometry.size());
+ if (geometry.topLeft() != oldGeometry.topLeft())
+ move(geometry.topLeft());
+ } // done
+ }
bool wasResized = testAttribute(Qt::WA_Resized);
Qt::WindowStates initialWindowState = windowState();
@@ -8207,7 +8220,7 @@ bool QWidget::event(QEvent *event)
#ifndef QT_NO_TOOLTIP
case QEvent::ToolTip:
if (!d->toolTip.isEmpty())
- QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this);
+ QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this, QRect(), d->toolTipDuration);
else
event->ignore();
break;
@@ -9251,6 +9264,10 @@ void QWidget::setSizePolicy(QSizePolicy policy)
setAttribute(Qt::WA_WState_OwnSizePolicy);
if (policy == d->size_policy)
return;
+
+ if (d->size_policy.retainSizeWhenHidden() != policy.retainSizeWhenHidden())
+ d->retainSizeWhenHiddenChanged = 1;
+
d->size_policy = policy;
#ifndef QT_NO_GRAPHICSVIEW
@@ -9261,6 +9278,7 @@ void QWidget::setSizePolicy(QSizePolicy policy)
#endif
updateGeometry();
+ d->retainSizeWhenHiddenChanged = 0;
if (isWindow() && d->maybeTopData())
d->topData()->sizeAdjusted = false;
@@ -9389,7 +9407,9 @@ void QWidgetPrivate::updateGeometry_helper(bool forceUpdate)
widgetItem->invalidateSizeCache();
QWidget *parent;
if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) {
- if (!q->isWindow() && !q->isHidden() && (parent = q->parentWidget())) {
+ const int isHidden = q->isHidden() && !size_policy.retainSizeWhenHidden() && !retainSizeWhenHiddenChanged;
+
+ if (!q->isWindow() && !isHidden && (parent = q->parentWidget())) {
if (parent->d_func()->layout)
parent->d_func()->layout->invalidate();
else if (parent->isVisible())
@@ -10019,6 +10039,13 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
#endif
+ // Don't set WA_NativeWindow on platforms that don't support it
+ if (attribute == Qt::WA_NativeWindow) {
+ QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
+ if (!platformIntegration->hasCapability(QPlatformIntegration::NativeWidgets))
+ return;
+ }
+
setAttribute_internal(attribute, on, data, d);
switch (attribute) {
@@ -10426,6 +10453,30 @@ QString QWidget::toolTip() const
Q_D(const QWidget);
return d->toolTip;
}
+
+/*!
+ \property QWidget::toolTipDuration
+ \brief the widget's tooltip duration
+ \since 5.2
+
+ Specifies how long time the tooltip will be displayed, in milliseconds.
+ If the value is -1 (default) the duration is calculated depending on the length of the tooltip.
+
+ \sa toolTip
+*/
+
+void QWidget::setToolTipDuration(int msec)
+{
+ Q_D(QWidget);
+ d->toolTipDuration = msec;
+}
+
+int QWidget::toolTipDuration() const
+{
+ Q_D(const QWidget);
+ return d->toolTipDuration;
+}
+
#endif // QT_NO_TOOLTIP
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index f90f2ee5f5..f579dbb9cd 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -178,6 +178,7 @@ class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice
Q_PROPERTY(bool windowModified READ isWindowModified WRITE setWindowModified DESIGNABLE isWindow)
#ifndef QT_NO_TOOLTIP
Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
+ Q_PROPERTY(int toolTipDuration READ toolTipDuration WRITE setToolTipDuration)
#endif
#ifndef QT_NO_STATUSTIP
Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip)
@@ -376,6 +377,8 @@ public:
#ifndef QT_NO_TOOLTIP
void setToolTip(const QString &);
QString toolTip() const;
+ void setToolTipDuration(int msec);
+ int toolTipDuration() const;
#endif
#ifndef QT_NO_STATUSTIP
void setStatusTip(const QString &);
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 50f32af8b0..0580f72e11 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -644,6 +644,7 @@ public:
QRegion dirty;
#ifndef QT_NO_TOOLTIP
QString toolTip;
+ int toolTipDuration;
#endif
#ifndef QT_NO_STATUSTIP
QString statusTip;
@@ -687,6 +688,7 @@ public:
QPalette::ColorRole bg_role : 8;
uint dirtyOpaqueChildren : 1;
uint isOpaque : 1;
+ uint retainSizeWhenHiddenChanged : 1;
uint inDirtyList : 1;
uint isScrolled : 1;
uint isMoved : 1;
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 675ea77b30..f2bd389769 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -559,7 +559,7 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
QPoint mapped = widget->mapFrom(m_widget, event->pos());
- QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers());
+ QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase());
QGuiApplication::sendSpontaneousEvent(widget, &translated);
}
diff --git a/src/widgets/styles/images/cleartext-16.png b/src/widgets/styles/images/cleartext-16.png
new file mode 100644
index 0000000000..74133bafff
--- /dev/null
+++ b/src/widgets/styles/images/cleartext-16.png
Binary files differ
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index ba6c222820..539cc70eb7 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -65,6 +65,7 @@
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qrubberband.h>
+#include "qtreeview.h"
#include <private/qcommonstylepixmaps_p.h>
#include <private/qmath_p.h>
#include <qdebug.h>
@@ -5096,11 +5097,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
ret = theme->themeHint(QPlatformTheme::ToolButtonStyle).toInt();
break;
case SH_RequestSoftwareInputPanel:
-#ifdef Q_OS_ANDROID
ret = RSIP_OnMouseClick;
-#else
- ret = RSIP_OnMouseClickAndAlreadyFocused;
-#endif
break;
case SH_ScrollBar_Transient:
ret = false;
@@ -5108,6 +5105,27 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
case SH_Menu_SupportsSections:
ret = false;
break;
+#ifndef QT_NO_TOOLTIP
+ case SH_ToolTip_WakeUpDelay:
+ ret = 700;
+ break;
+ case SH_ToolTip_FallAsleepDelay:
+ ret = 2000;
+ break;
+#endif
+ case SH_Widget_Animate:
+#ifndef QT_NO_TREEVIEW
+ if (qobject_cast<const QTreeView*>(widget)) {
+ ret = false;
+ } else
+#endif
+ {
+ ret = true;
+ }
+ break;
+ case SH_Splitter_OpaqueResize:
+ ret = true;
+ break;
default:
ret = 0;
break;
@@ -5288,6 +5306,13 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti
}
}
break;
+ case SP_LineEditClearButton: {
+ QString themeName = rtl ? QStringLiteral("edit-clear-locationbar-ltr") : QStringLiteral("edit-clear-locationbar-rtl");
+ if (!QIcon::hasThemeIcon(themeName))
+ themeName = QStringLiteral("edit-clear");
+ pixmap = QIcon::fromTheme(themeName).pixmap(16);
+ }
+ break;
default:
break;
}
@@ -5416,6 +5441,8 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti
return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"));
case SP_MediaVolumeMuted:
return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"));
+ case SP_LineEditClearButton:
+ return QPixmap(QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-16.png"));
#endif // QT_NO_IMAGEFORMAT_PNG
default:
break;
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index 769d822108..c53a21e59a 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -756,8 +756,9 @@ void QGtkStylePrivate::removeWidgetFromMap(const QHashableLatin1Literal &path)
WidgetMap *map = gtkWidgetMap();
WidgetMap::iterator it = map->find(path);
if (it != map->end()) {
- free(const_cast<char *>(it.key().data()));
+ char* keyData = const_cast<char *>(it.key().data());
map->erase(it);
+ free(keyData);
}
}
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index dccc9ff3ce..77f869f036 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -53,6 +53,7 @@
#endif
#include <limits.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -1894,6 +1895,19 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_Menu_SupportsSections Determines if the style displays sections in menus or treat them as
plain separators. Sections are separators with a text and icon hint.
+ \value SH_ToolTip_WakeUpDelay Determines the delay before a tooltip is shown, in milliseconds.
+
+ \value SH_ToolTip_FallAsleepDelay Determines the delay (in milliseconds) before a new wake time is needed when
+ a tooltip is shown (notice: shown, not hidden). When a new wake isn't needed, a user-requested tooltip
+ will be shown nearly instantly.
+
+ \value SH_Widget_Animate Determines if the widget should show animations or not, for example
+ a transition between checked and unchecked statuses in a checkbox.
+ This enum value has been introduced in Qt 5.2.
+
+ \value SH_Splitter_OpaqueResize Determines if resizing is opaque
+ This enum value has been introduced in Qt 5.2
+
\sa styleHint()
*/
@@ -1986,6 +2000,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SP_MediaSeekBackward Icon indicating that media should seek backward.
\value SP_MediaVolume Icon indicating a volume control.
\value SP_MediaVolumeMuted Icon indicating a muted volume control.
+ \value SP_LineEditClearButton Icon for a standard clear button in a QLineEdit. This enum value was added in Qt 5.2.
\value SP_CustomBase Base value for custom standard pixmaps;
custom values must be greater than this value.
@@ -2323,7 +2338,7 @@ QDebug operator<<(QDebug debug, QStyle::State state)
if (state & QStyle::State_Top) states << QLatin1String("Top");
if (state & QStyle::State_UpArrow) states << QLatin1String("UpArrow");
- qSort(states);
+ std::sort(states.begin(), states.end());
debug << states.join(QLatin1String(" | "));
debug << ')';
#else
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index beafad326e..bbb216bf92 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -698,6 +698,10 @@ public:
SH_RequestSoftwareInputPanel,
SH_ScrollBar_Transient,
SH_Menu_SupportsSections,
+ SH_ToolTip_WakeUpDelay,
+ SH_ToolTip_FallAsleepDelay,
+ SH_Widget_Animate,
+ SH_Splitter_OpaqueResize,
// Add new style hint values here
SH_CustomBase = 0xf0000000
@@ -777,6 +781,7 @@ public:
SP_MediaSeekBackward,
SP_MediaVolume,
SP_MediaVolumeMuted,
+ SP_LineEditClearButton,
// do not add any values below/greater than this
SP_CustomBase = 0xf0000000
};
diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc
index 28ad484032..c063ec5036 100644
--- a/src/widgets/styles/qstyle.qrc
+++ b/src/widgets/styles/qstyle.qrc
@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/qt-project.org/styles/commonstyle">
+ <file>images/cleartext-16.png</file>
<file>images/filelink-16.png</file>
<file>images/filelink-32.png</file>
<file>images/filelink-128.png</file>
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index be89abf2b2..85520d3c40 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -1096,7 +1096,7 @@ void QRenderRule::fixupBorder(int nativeWidth)
bd->borders[i] = nativeWidth;
// intentional fall through
default:
- if (!bd->colors[i].style() != Qt::NoBrush) // auto-acquire 'color'
+ if (bd->colors[i].style() == Qt::NoBrush) // auto-acquire 'color'
bd->colors[i] = color;
break;
}
@@ -4810,10 +4810,22 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
switch (ct) {
case CT_SpinBox: // ### hopelessly broken QAbstractSpinBox (part 1)
- if (rule.hasBox() || !rule.hasNativeBorder())
- return csz;
- return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
- : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ // Add some space for the up/down buttons
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
+ if (subRule.hasDrawable()) {
+ QRect r = positionRect(w, rule, subRule, PseudoElement_SpinBoxUpButton,
+ opt->rect, opt->direction);
+ sz += QSize(r.width(), 0);
+ } else {
+ QSize defaultUpSize = defaultSize(w, subRule.size(), spinbox->rect, PseudoElement_SpinBoxUpButton);
+ sz += QSize(defaultUpSize.width(), 0);
+ }
+ if (rule.hasBox() || !rule.hasNativeBorder())
+ sz = rule.boxSize(sz);
+ return sz;
+ }
+ break;
case CT_ToolButton:
if (rule.hasBox() || !rule.hasNativeBorder() || !rule.baseStyleCanDraw())
sz += QSize(3, 3); // ### broken QToolButton
@@ -4858,14 +4870,8 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
case CT_GroupBox:
case CT_LineEdit:
#ifndef QT_NO_SPINBOX
- // ### hopelessly broken QAbstractSpinBox (part 2)
- if (QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(w ? w->parentWidget() : 0)) {
- QRenderRule rule = renderRule(spinBox, opt);
- if (rule.hasBox() || !rule.hasNativeBorder())
- return csz;
- return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
- : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
- }
+ if (qobject_cast<QAbstractSpinBox *>(w ? w->parentWidget() : 0))
+ return csz; // we only care about the size hint of the line edit
#endif
if (rule.hasBox() || !rule.hasNativeBorder()) {
return rule.boxSize(sz);
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
index 3b3c27f6cb..506a148d2f 100644
--- a/src/widgets/styles/qwindowsxpstyle.cpp
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -72,6 +72,8 @@
#include <qvarlengtharray.h>
#include <qdebug.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
// Runtime resolved theme engine function calls
@@ -277,7 +279,7 @@ void QWindowsXPStylePrivate::init(bool force)
ref.ref();
useXP(true);
- qFill(m_themes, m_themes + NThemes, HTHEME(0));
+ std::fill(m_themes, m_themes + NThemes, HTHEME(0));
}
/* \internal
@@ -4306,7 +4308,7 @@ void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData)
}
}
}
- qSort(all_props);
+ std::sort(all_props.begin(), all_props.end());
{// List all properties
printf("part properties count = %d:\n", all_props.count());
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index 5204b85a9a..347e5701c0 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -57,84 +57,19 @@
#include <qpa/qplatformnativeinterface.h>
#include <qdebug.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#include <X11/Xatom.h>
-
#ifndef QT_NO_SYSTEMTRAYICON
QT_BEGIN_NAMESPACE
-enum {
- SYSTEM_TRAY_REQUEST_DOCK = 0,
- SYSTEM_TRAY_BEGIN_MESSAGE = 1,
- SYSTEM_TRAY_CANCEL_MESSAGE =2
-};
-
-// ### fixme (15.3.2012): The following issues need to be resolved:
-// - Tracking of the actual tray window for DestroyNotify and re-creation
-// of the icons on the new window should it change (see Qt 4.X).
-
-// Global context for the X11 system tray containing a display for the primary
-// screen and a selection atom from which the tray window can be determined.
-class QX11SystemTrayContext
-{
-public:
- QX11SystemTrayContext();
- ~QX11SystemTrayContext();
-
- bool isValid() const { return m_systemTraySelection != 0; }
-
- inline Display *display() const { return m_display; }
- inline int screenNumber() const { return m_screenNumber; }
- Window locateSystemTray() const;
-
-private:
- Display *m_display;
- int m_screenNumber;
- Atom m_systemTraySelection;
-};
-
-QX11SystemTrayContext::QX11SystemTrayContext() : m_display(0), m_screenNumber(0), m_systemTraySelection(0)
-{
- QScreen *screen = QGuiApplication::primaryScreen();
- if (!screen) {
- qWarning("%s: No screen.", Q_FUNC_INFO);
- return;
- }
- void *displayV = QGuiApplication::platformNativeInterface()->nativeResourceForScreen(QByteArrayLiteral("display"), screen);
- if (!displayV) {
- qWarning("%s: Unable to obtain X11 display of primary screen.", Q_FUNC_INFO);
- return;
- }
-
- m_display = static_cast<Display *>(displayV);
-
- const QByteArray netSysTray = "_NET_SYSTEM_TRAY_S" + QByteArray::number(m_screenNumber);
- m_systemTraySelection = XInternAtom(m_display, netSysTray.constData(), False);
- if (!m_systemTraySelection) {
- qWarning("%s: Unable to retrieve atom '%s'.", Q_FUNC_INFO, netSysTray.constData());
- return;
- }
-}
-
-Window QX11SystemTrayContext::locateSystemTray() const
+static inline unsigned long locateSystemTray()
{
- if (isValid())
- return XGetSelectionOwner(m_display, m_systemTraySelection);
- return 0;
+ return (unsigned long)QGuiApplication::platformNativeInterface()->nativeResourceForScreen(QByteArrayLiteral("traywindow"), QGuiApplication::primaryScreen());
}
-QX11SystemTrayContext::~QX11SystemTrayContext()
-{
-}
-
-Q_GLOBAL_STATIC(QX11SystemTrayContext, qX11SystemTrayContext)
-
// System tray widget. Could be replaced by a QWindow with
// a backing store if it did not need tooltip handling.
class QSystemTrayIconSys : public QWidget
{
+ Q_OBJECT
public:
explicit QSystemTrayIconSys(QSystemTrayIcon *q);
@@ -149,7 +84,12 @@ protected:
virtual bool event(QEvent *);
virtual void paintEvent(QPaintEvent *);
+private slots:
+ void systemTrayWindowChanged(QScreen *screen);
+
private:
+ bool addToTray();
+
QSystemTrayIcon *q;
};
@@ -159,47 +99,59 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
{
setObjectName(QStringLiteral("QSystemTrayIconSys"));
setToolTip(q->toolTip());
- QX11SystemTrayContext *context = qX11SystemTrayContext();
- Q_ASSERT(context->isValid());
setAttribute(Qt::WA_AlwaysShowToolTips, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_QuitOnClose, false);
const QSize size(22, 22); // Gnome, standard size
setGeometry(QRect(QPoint(0, 0), size));
setMinimumSize(size);
+ addToTray();
+}
+
+bool QSystemTrayIconSys::addToTray()
+{
+ if (!locateSystemTray())
+ return false;
+
createWinId();
setMouseTracking(true);
- Display *display = context->display();
-
- // Request to be a tray window according to GNOME, NET WM Specification
- static Atom netwm_tray_atom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", False);
- long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, static_cast<long>(winId()), 0, 0 };
- XEvent ev;
- memset(&ev, 0, sizeof(ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.window = context->locateSystemTray();
- ev.xclient.message_type = netwm_tray_atom;
- ev.xclient.format = 32;
- memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l));
- XSendEvent(display, ev.xclient.window, False, 0, &ev);
+ bool requestResult = false;
+ if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(),
+ "requestSystemTrayWindowDock", Qt::DirectConnection,
+ Q_RETURN_ARG(bool, requestResult),
+ Q_ARG(const QWindow *, windowHandle()))
+ || !requestResult) {
+ qWarning("requestSystemTrayWindowDock failed.");
+ return false;
+ }
show();
+ return true;
}
-QRect QSystemTrayIconSys::globalGeometry() const
+void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
{
- QX11SystemTrayContext *context = qX11SystemTrayContext();
- ::Window dummy;
- int x, y, rootX, rootY;
- unsigned int width, height, border, depth;
- // Use X11 API since we are parented on the tray, about which the QWindow does not know.
- XGetGeometry(context->display(), winId(), &dummy, &x, &y, &width, &height, &border, &depth);
- XTranslateCoordinates(context->display(), winId(),
- XRootWindow(context->display(), context->screenNumber()),
- x, y, &rootX, &rootY, &dummy);
- return QRect(QPoint(rootX, rootY), QSize(width, height));
+ if (locateSystemTray()) {
+ addToTray();
+ } else {
+ QBalloonTip::hideBalloon();
+ hide(); // still no luck
+ destroy();
+ }
}
+QRect QSystemTrayIconSys::globalGeometry() const
+{
+ QRect result;
+ if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(),
+ "systemTrayWindowGlobalGeometry", Qt::DirectConnection,
+ Q_RETURN_ARG(QRect, result),
+ Q_ARG(const QWindow *, windowHandle()))
+ || !result.isValid()) {
+ qWarning("systemTrayWindowGlobalGeometry failed.");
+ }
+ return result;
+}
void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)
{
@@ -268,8 +220,11 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
void QSystemTrayIconPrivate::install_sys()
{
Q_Q(QSystemTrayIcon);
- if (!sys && qX11SystemTrayContext()->isValid())
+ if (!sys && locateSystemTray()) {
sys = new QSystemTrayIconSys(q);
+ QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
+ sys, SLOT(systemTrayWindowChanged(QScreen*)));
+ }
}
QRect QSystemTrayIconPrivate::geometry_sys() const
@@ -313,7 +268,7 @@ bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
{
const QString platform = QGuiApplication::platformName();
if (platform.compare(QStringLiteral("xcb"), Qt::CaseInsensitive) == 0)
- return qX11SystemTrayContext()->locateSystemTray() != None;
+ return locateSystemTray();
return false;
}
@@ -334,4 +289,7 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QStri
}
QT_END_NAMESPACE
+
+#include "qsystemtrayicon_x11.moc"
+
#endif //QT_NO_SYSTEMTRAYICON
diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri
index 598a3082c0..072c736f71 100644
--- a/src/widgets/util/util.pri
+++ b/src/widgets/util/util.pri
@@ -31,7 +31,6 @@ win32:!wince* {
SOURCES += util/qsystemtrayicon_win.cpp
} else:contains(QT_CONFIG, xcb) {
SOURCES += util/qsystemtrayicon_x11.cpp
- CONFIG += x11
} else {
SOURCES += util/qsystemtrayicon_qpa.cpp
}
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
index 3f9b28a883..cdadde5cc1 100644
--- a/src/widgets/widgets/qabstractbutton.cpp
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -52,6 +52,8 @@
#include "qaccessible.h"
#endif
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
#define AUTO_REPEAT_DELAY 300
@@ -231,7 +233,7 @@ void QButtonGroup::addButton(QAbstractButton *button, int id)
if (ids.isEmpty())
d->mapping[button] = -2;
else {
- qSort(ids);
+ std::sort(ids.begin(), ids.end());
d->mapping[button] = ids.first()-1;
}
} else {
@@ -575,6 +577,20 @@ void QAbstractButtonPrivate::emitReleased()
#endif
}
+void QAbstractButtonPrivate::emitToggled(bool checked)
+{
+ Q_Q(QAbstractButton);
+ QPointer<QAbstractButton> guard(q);
+ emit q->toggled(checked);
+#ifndef QT_NO_BUTTONGROUP
+ if (guard && group) {
+ emit group->buttonToggled(group->id(q), checked);
+ if (guard && group)
+ emit group->buttonToggled(q, checked);
+ }
+#endif
+}
+
/*!
Constructs an abstract button with a \a parent.
*/
@@ -758,7 +774,7 @@ void QAbstractButton::setChecked(bool checked)
if (guard && checked)
d->notifyChecked();
if (guard)
- emit toggled(checked);
+ d->emitToggled(checked);
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/widgets/widgets/qabstractbutton_p.h b/src/widgets/widgets/qabstractbutton_p.h
index 4585728848..a148e60717 100644
--- a/src/widgets/widgets/qabstractbutton_p.h
+++ b/src/widgets/widgets/qabstractbutton_p.h
@@ -103,6 +103,7 @@ public:
void emitPressed();
void emitReleased();
void emitClicked();
+ void emitToggled(bool checked);
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 900e95f4da..e7827055fb 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -167,6 +167,7 @@ QT_BEGIN_NAMESPACE
QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
:hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
+ shownOnce(false), sizeAdjustPolicy(QAbstractScrollArea::AdjustIgnored),
viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
xoffset(0), yoffset(0), viewportFilter(0)
#ifdef Q_WS_WIN
@@ -527,6 +528,19 @@ void QAbstractScrollAreaPrivate::layoutChildren()
}
/*!
+ \enum QAbstractScrollArea::SizeAdjustPolicy
+ \since 5.2
+
+ This enum specifies how the size hint of the QAbstractScrollArea should
+ adjust when the size of the viewport changes.
+
+ \value AdjustIgnored The scroll area will behave like before - and not do any adjust.
+ \value AdjustToContents The scroll area will always adjust to the viewport
+ \value AdjustToContentsOnFirstShow The scroll area will adjust to its viewport the first time it is shown.
+*/
+
+
+/*!
\internal
Creates a new QAbstractScrollAreaPrivate, \a dd with the given \a parent.
@@ -983,6 +997,13 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::Resize:
d->layoutChildren();
break;
+ case QEvent::Show:
+ if (!d->shownOnce && d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContentsOnFirstShow) {
+ d->sizeHint = QSize();
+ updateGeometry();
+ }
+ d->shownOnce = true;
+ return QFrame::event(e);
case QEvent::Paint: {
QStyleOption option;
option.initFrom(this);
@@ -1533,17 +1554,70 @@ QSize QAbstractScrollArea::minimumSizeHint() const
}
/*!
+ Returns the sizeHint property of the scroll area. The size is determined by using
+ viewportSizeHint() plus some extra space for scroll bars, if needed.
\reimp
*/
QSize QAbstractScrollArea::sizeHint() const
{
- return QSize(256, 192);
-#if 0
Q_D(const QAbstractScrollArea);
- int h = qMax(10, fontMetrics().height());
- int f = 2 * d->frameWidth;
- return QSize((6 * h) + f, (4 * h) + f);
-#endif
+ if (d->sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
+ return QSize(256, 192);
+
+ if (!d->sizeHint.isValid() || d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents) {
+ const int f = 2 * d->frameWidth;
+ const QSize frame( f, f );
+ const QSize scrollbars(d->vbarpolicy == Qt::ScrollBarAlwaysOn ? d->vbar->sizeHint().width() : 0,
+ d->hbarpolicy == Qt::ScrollBarAlwaysOn ? d->hbar->sizeHint().height() : 0);
+ d->sizeHint = frame + scrollbars + viewportSizeHint();
+ }
+ return d->sizeHint;
+}
+
+/*!
+ \since 5.2
+ Returns the recommended size for the viewport.
+ The default implementation returns viewport()->sizeHint().
+ Note that the size is just the viewport's size, without any scroll bars visible.
+ */
+QSize QAbstractScrollArea::viewportSizeHint() const
+{
+ Q_D(const QAbstractScrollArea);
+ if (d->viewport) {
+ const QSize sh = d->viewport->sizeHint();
+ if (sh.isValid()) {
+ return sh;
+ }
+ }
+ const int h = qMax(10, fontMetrics().height());
+ return QSize(6 * h, 4 * h);
+}
+
+/*!
+ \since 5.2
+ \property QAbstractScrollArea::sizeAdjustPolicy
+ This property holds the policy describing how the size of the scroll area changes when the
+ size of the viewport changes.
+
+ The default policy is QAbstractScrollArea::AdjustIgnored.
+ Changing this property might actually resize the scrollarea.
+*/
+
+QAbstractScrollArea::SizeAdjustPolicy QAbstractScrollArea::sizeAdjustPolicy() const
+{
+ Q_D(const QAbstractScrollArea);
+ return d->sizeAdjustPolicy;
+}
+
+void QAbstractScrollArea::setSizeAdjustPolicy(SizeAdjustPolicy policy)
+{
+ Q_D(QAbstractScrollArea);
+ if (d->sizeAdjustPolicy == policy)
+ return;
+
+ d->sizeAdjustPolicy = policy;
+ d->sizeHint = QSize();
+ updateGeometry();
}
/*!
@@ -1559,16 +1633,6 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
-/*!
- \internal
-
- This method is reserved for future use.
-*/
-QSize QAbstractScrollArea::viewportSizeHint() const
-{
- return QSize();
-}
-
QT_END_NAMESPACE
#include "moc_qabstractscrollarea.cpp"
diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h
index ccf16b5e5c..fb9562db1b 100644
--- a/src/widgets/widgets/qabstractscrollarea.h
+++ b/src/widgets/widgets/qabstractscrollarea.h
@@ -56,13 +56,22 @@ class QAbstractScrollAreaPrivate;
class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame
{
Q_OBJECT
+
+ Q_ENUMS(SizeAdjustPolicy)
Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy READ verticalScrollBarPolicy WRITE setVerticalScrollBarPolicy)
Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy READ horizontalScrollBarPolicy WRITE setHorizontalScrollBarPolicy)
+ Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
public:
explicit QAbstractScrollArea(QWidget* parent=0);
~QAbstractScrollArea();
+ enum SizeAdjustPolicy {
+ AdjustIgnored,
+ AdjustToContentsOnFirstShow,
+ AdjustToContents
+ };
+
Qt::ScrollBarPolicy verticalScrollBarPolicy() const;
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy);
QScrollBar *verticalScrollBar() const;
@@ -89,6 +98,9 @@ public:
virtual void setupViewport(QWidget *viewport);
+ SizeAdjustPolicy sizeAdjustPolicy() const;
+ void setSizeAdjustPolicy(SizeAdjustPolicy policy);
+
protected:
QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0);
void setViewportMargins(int left, int top, int right, int bottom);
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
index 34d767fe29..3093c2f812 100644
--- a/src/widgets/widgets/qabstractscrollarea_p.h
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -75,6 +75,10 @@ public:
QScrollBar *hbar, *vbar;
Qt::ScrollBarPolicy vbarpolicy, hbarpolicy;
+ bool shownOnce;
+ mutable QSize sizeHint;
+ QAbstractScrollArea::SizeAdjustPolicy sizeAdjustPolicy;
+
QWidget *viewport;
QWidget *cornerWidget;
QRect cornerPaintingRect;
diff --git a/src/widgets/widgets/qbuttongroup.cpp b/src/widgets/widgets/qbuttongroup.cpp
index f22910007f..c484b154fd 100644
--- a/src/widgets/widgets/qbuttongroup.cpp
+++ b/src/widgets/widgets/qbuttongroup.cpp
@@ -174,6 +174,27 @@
*/
/*!
+ \fn void QButtonGroup::buttonToggled(QAbstractButton *button, bool checked)
+ \since 5.2
+
+ This signal is emitted when the given \a button is toggled.
+ \a checked is true if the button is checked, or false if the button is unchecked.
+
+ \sa QAbstractButton::toggled()
+*/
+
+/*!
+ \fn void QButtonGroup::buttonToggled(int id, bool checked)
+ \since 5.2
+
+ This signal is emitted when a button with the given \a id is toggled.
+ \a checked is true if the button is checked, or false if the button is unchecked.
+
+ \sa QAbstractButton::toggled()
+*/
+
+
+/*!
\fn void QButtonGroup::addButton(QAbstractButton *button, int id = -1);
Adds the given \a button to the button group. If \a id is -1,
diff --git a/src/widgets/widgets/qbuttongroup.h b/src/widgets/widgets/qbuttongroup.h
index 84fe26e0df..06656bf18c 100644
--- a/src/widgets/widgets/qbuttongroup.h
+++ b/src/widgets/widgets/qbuttongroup.h
@@ -85,7 +85,8 @@ Q_SIGNALS:
void buttonPressed(int);
void buttonReleased(QAbstractButton *);
void buttonReleased(int);
-
+ void buttonToggled(QAbstractButton *, bool);
+ void buttonToggled(int, bool);
private:
Q_DISABLE_COPY(QButtonGroup)
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index afe8f1c3f4..90310308c3 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -407,7 +407,7 @@ void QComboBoxPrivateContainer::leaveEvent(QEvent *)
}
QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent)
- : QFrame(parent, Qt::Popup), combo(parent), view(0), top(0), bottom(0)
+ : QFrame(parent, Qt::Popup), combo(parent), view(0), top(0), bottom(0), maybeIgnoreMouseButtonRelease(false)
{
// we need the combobox and itemview
Q_ASSERT(parent);
@@ -667,10 +667,15 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
}
}
break;
+ case QEvent::MouseButtonPress:
+ maybeIgnoreMouseButtonRelease = false;
+ break;
case QEvent::MouseButtonRelease: {
+ bool ignoreEvent = maybeIgnoreMouseButtonRelease && popupTimer.elapsed() < QApplication::doubleClickInterval();
+
QMouseEvent *m = static_cast<QMouseEvent *>(e);
if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid()
- && !blockMouseReleaseTimer.isActive()
+ && !blockMouseReleaseTimer.isActive() && !ignoreEvent
&& (view->currentIndex().flags() & Qt::ItemIsEnabled)
&& (view->currentIndex().flags() & Qt::ItemIsSelectable)) {
combo->hidePopup();
@@ -2086,6 +2091,20 @@ QString QComboBox::currentText() const
}
/*!
+ \property QComboBox::currentData
+ \brief the data for the current item
+ \since 5.2
+
+ By default, for an empty combo box or a combo box in which no current
+ item is set, this property contains an invalid QVariant.
+*/
+QVariant QComboBox::currentData(int role) const
+{
+ Q_D(const QComboBox);
+ return d->currentIndex.data(role);
+}
+
+/*!
Returns the text for the given \a index in the combobox.
*/
QString QComboBox::itemText(int index) const
@@ -2548,6 +2567,7 @@ void QComboBox::showPopup()
container->setUpdatesEnabled(false);
#endif
+ bool startTimer = !container->isVisible();
container->raise();
container->show();
container->updateScrollers();
@@ -2567,6 +2587,10 @@ void QComboBox::showPopup()
if (QApplication::keypadNavigationEnabled())
view()->setEditFocus(true);
#endif
+ if (startTimer) {
+ container->popupTimer.start();
+ container->maybeIgnoreMouseButtonRelease = true;
+ }
}
/*!
@@ -2862,6 +2886,11 @@ void QComboBox::mousePressEvent(QMouseEvent *e)
}
#endif
showPopup();
+ // The code below ensures that regular mousepress and pick item still works
+ // If it was not called the viewContainer would ignore event since it didn't have
+ // a mousePressEvent first.
+ if (d->viewContainer())
+ d->viewContainer()->maybeIgnoreMouseButtonRelease = false;
} else {
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && d->lineEdit) {
diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h
index 2fafe79f7a..0002cd08cb 100644
--- a/src/widgets/widgets/qcombobox.h
+++ b/src/widgets/widgets/qcombobox.h
@@ -66,6 +66,7 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget
Q_PROPERTY(int count READ count)
Q_PROPERTY(QString currentText READ currentText WRITE setCurrentText NOTIFY currentTextChanged USER true)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ Q_PROPERTY(QVariant currentData READ currentData)
Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount)
Q_PROPERTY(InsertPolicy insertPolicy READ insertPolicy WRITE setInsertPolicy)
@@ -167,8 +168,8 @@ public:
void setModelColumn(int visibleColumn);
int currentIndex() const;
-
QString currentText() const;
+ QVariant currentData(int role = Qt::UserRole) const;
QString itemText(int index) const;
QIcon itemIcon(int index) const;
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 07ba9b0925..1ad2aa455a 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -254,6 +254,10 @@ private:
QAbstractItemView *view;
QComboBoxPrivateScroller *top;
QComboBoxPrivateScroller *bottom;
+ bool maybeIgnoreMouseButtonRelease;
+ QElapsedTimer popupTimer;
+
+ friend class QComboBox;
};
class QComboMenuDelegate : public QAbstractItemDelegate
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index bc5d84e259..226969cdd1 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -669,6 +669,21 @@ QDialogButtonBox::QDialogButtonBox(Qt::Orientation orientation, QWidget *parent)
}
/*!
+ \since 5.2
+
+ Constructs a horizontal button box with the given \a parent, containing
+ the standard buttons specified by \a buttons.
+
+ \sa orientation, addButton()
+*/
+QDialogButtonBox::QDialogButtonBox(StandardButtons buttons, QWidget *parent)
+ : QWidget(*new QDialogButtonBoxPrivate(Qt::Horizontal), parent, 0)
+{
+ d_func()->initLayout();
+ d_func()->createStandardButtons(buttons);
+}
+
+/*!
Constructs a button box with the given \a orientation and \a parent, containing
the standard buttons specified by \a buttons.
diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h
index 6715c590e2..d8e1a997d4 100644
--- a/src/widgets/widgets/qdialogbuttonbox.h
+++ b/src/widgets/widgets/qdialogbuttonbox.h
@@ -115,7 +115,8 @@ public:
QDialogButtonBox(QWidget *parent = 0);
QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = 0);
- QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation = Qt::Horizontal,
+ explicit QDialogButtonBox(StandardButtons buttons, QWidget *parent = 0);
+ QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation,
QWidget *parent = 0);
~QDialogButtonBox();
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 5f929caf03..0b0efa2bdf 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -54,6 +54,88 @@
QT_BEGIN_NAMESPACE
+static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script)
+{
+ switch (script) {
+ case QLocale::ArabicScript:
+ return QFontDatabase::Arabic;
+ case QLocale::CyrillicScript:
+ return QFontDatabase::Cyrillic;
+ case QLocale::GurmukhiScript:
+ return QFontDatabase::Gurmukhi;
+ case QLocale::SimplifiedHanScript:
+ return QFontDatabase::SimplifiedChinese;
+ case QLocale::TraditionalHanScript:
+ return QFontDatabase::TraditionalChinese;
+ case QLocale::LatinScript:
+ return QFontDatabase::Latin;
+ case QLocale::ArmenianScript:
+ return QFontDatabase::Armenian;
+ case QLocale::BengaliScript:
+ return QFontDatabase::Bengali;
+ case QLocale::DevanagariScript:
+ return QFontDatabase::Devanagari;
+ case QLocale::GeorgianScript:
+ return QFontDatabase::Georgian;
+ case QLocale::GreekScript:
+ return QFontDatabase::Greek;
+ case QLocale::GujaratiScript:
+ return QFontDatabase::Gujarati;
+ case QLocale::HebrewScript:
+ return QFontDatabase::Hebrew;
+ case QLocale::JapaneseScript:
+ return QFontDatabase::Japanese;
+ case QLocale::KhmerScript:
+ return QFontDatabase::Khmer;
+ case QLocale::KannadaScript:
+ return QFontDatabase::Kannada;
+ case QLocale::KoreanScript:
+ return QFontDatabase::Korean;
+ case QLocale::LaoScript:
+ return QFontDatabase::Lao;
+ case QLocale::MalayalamScript:
+ return QFontDatabase::Malayalam;
+ case QLocale::MyanmarScript:
+ return QFontDatabase::Myanmar;
+ case QLocale::TamilScript:
+ return QFontDatabase::Tamil;
+ case QLocale::TeluguScript:
+ return QFontDatabase::Telugu;
+ case QLocale::ThaanaScript:
+ return QFontDatabase::Thaana;
+ case QLocale::ThaiScript:
+ return QFontDatabase::Thai;
+ case QLocale::TibetanScript:
+ return QFontDatabase::Tibetan;
+ case QLocale::SinhalaScript:
+ return QFontDatabase::Sinhala;
+ case QLocale::SyriacScript:
+ return QFontDatabase::Syriac;
+ case QLocale::OriyaScript:
+ return QFontDatabase::Oriya;
+ case QLocale::OghamScript:
+ return QFontDatabase::Ogham;
+ case QLocale::RunicScript:
+ return QFontDatabase::Runic;
+ case QLocale::NkoScript:
+ return QFontDatabase::Nko;
+ default:
+ return QFontDatabase::Any;
+ }
+}
+
+static QFontDatabase::WritingSystem writingSystemFromLocale()
+{
+ QStringList uiLanguages = QLocale::system().uiLanguages();
+ QLocale::Script script;
+ if (!uiLanguages.isEmpty())
+ script = QLocale(uiLanguages.at(0)).script();
+ else
+ script = QLocale::system().script();
+
+ return writingSystemFromScript(script);
+}
+
static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
{
QList<QFontDatabase::WritingSystem> writingSystems = QFontDatabase().writingSystems(font.family());
@@ -66,7 +148,22 @@ static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool
if (writingSystems.isEmpty())
return QFontDatabase::Any;
- QFontDatabase::WritingSystem system = writingSystems.last();
+ QFontDatabase::WritingSystem system = writingSystemFromLocale();
+
+ if (writingSystems.contains(system))
+ return system;
+
+ if (system == QFontDatabase::TraditionalChinese
+ && writingSystems.contains(QFontDatabase::SimplifiedChinese)) {
+ return QFontDatabase::SimplifiedChinese;
+ }
+
+ if (system == QFontDatabase::SimplifiedChinese
+ && writingSystems.contains(QFontDatabase::TraditionalChinese)) {
+ return QFontDatabase::TraditionalChinese;
+ }
+
+ system = writingSystems.last();
if (!*hasLatin) {
// we need to show something
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 816e7be8fd..adf70fde66 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -350,7 +350,7 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText)
Q_D(QLineEdit);
if (d->placeholderText != placeholderText) {
d->placeholderText = placeholderText;
- if (!hasFocus())
+ if (d->control->text().isEmpty())
update();
}
}
@@ -419,6 +419,96 @@ bool QLineEdit::hasFrame() const
return d->frame;
}
+/*!
+ \enum QLineEdit::ActionPosition
+
+ This enum type describes how a line edit should display the action widgets to be
+ added.
+
+ \value LeadingPosition The widget is displayed to the left of the text
+ when using layout direction \c Qt::LeftToRight or to
+ the right when using \c Qt::RightToLeft, respectively.
+
+ \value TrailingPosition The widget is displayed to the right of the text
+ when using layout direction \c Qt::LeftToRight or to
+ the left when using \c Qt::RightToLeft, respectively.
+
+ \sa addAction(), removeAction(), QWidget::layoutDirection
+
+ \since 5.2
+*/
+
+/*!
+ \fn void QLineEdit::addAction(QAction *action)
+ \overload
+ \internal
+*/
+
+/*!
+ \overload
+
+ Adds the \a action to the list of actions at the \a position.
+
+ \since 5.2
+*/
+
+void QLineEdit::addAction(QAction *action, ActionPosition position)
+{
+ Q_D(QLineEdit);
+ QWidget::addAction(action);
+ d->addAction(action, 0, position);
+}
+
+/*!
+ \overload
+
+ Creates a new action with the given \a icon at the \a position.
+
+ \since 5.2
+*/
+
+QAction *QLineEdit::addAction(const QIcon &icon, ActionPosition position)
+{
+ QAction *result = new QAction(icon, QString(), this);
+ addAction(result, position);
+ return result;
+}
+
+/*!
+ \property QLineEdit::clearButtonEnabled
+ \brief Whether the line edit displays a clear button when it is not empty.
+
+ If enabled, the line edit displays a trailing \e clear button when it contains
+ some text, otherwise the line edit does not show a clear button (the
+ default).
+
+ \sa addAction(), removeAction()
+ \since 5.2
+*/
+
+static const char clearButtonActionNameC[] = "_q_qlineeditclearaction";
+
+void QLineEdit::setClearButtonEnabled(bool enable)
+{
+ Q_D(QLineEdit);
+ if (enable == isClearButtonEnabled())
+ return;
+ if (enable) {
+ QAction *clearAction = new QAction(d->clearButtonIcon(), QString(), this);
+ clearAction->setObjectName(QLatin1String(clearButtonActionNameC));
+ d->addAction(clearAction, 0, QLineEdit::TrailingPosition, QLineEditPrivate::SideWidgetClearButton | QLineEditPrivate::SideWidgetFadeInWithText);
+ } else {
+ QAction *clearAction = findChild<QAction *>(QLatin1String(clearButtonActionNameC));
+ Q_ASSERT(clearAction);
+ removeAction(clearAction);
+ delete clearAction;
+ }
+}
+
+bool QLineEdit::isClearButtonEnabled() const
+{
+ return findChild<QAction *>(QLatin1String(clearButtonActionNameC));
+}
void QLineEdit::setFrame(bool enable)
{
@@ -605,7 +695,7 @@ QSize QLineEdit::sizeHint() const
+ d->topTextMargin + d->bottomTextMargin
+ d->topmargin + d->bottommargin;
int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
- + d->leftTextMargin + d->rightTextMargin
+ + d->effectiveLeftTextMargin() + d->effectiveRightTextMargin()
+ d->leftmargin + d->rightmargin; // "some"
QStyleOptionFrameV2 opt;
initStyleOption(&opt);
@@ -966,7 +1056,6 @@ void QLineEdit::setDragEnabled(bool b)
d->dragEnabled = b;
}
-
/*!
\property QLineEdit::cursorMoveStyle
\brief the movement style of cursor in this line edit
@@ -1349,8 +1438,11 @@ bool QLineEdit::event(QEvent * e)
|| style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
d->setCursorVisible(true);
}
+ } else if (e->type() == QEvent::ActionRemoved) {
+ d->removeAction(static_cast<QActionEvent *>(e));
+ } else if (e->type() == QEvent::Resize) {
+ d->positionSideWidgets();
}
-
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled()) {
if (e->type() == QEvent::EnterEditFocus) {
@@ -1776,9 +1868,9 @@ void QLineEdit::paintEvent(QPaintEvent *)
initStyleOption(&panel);
style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
- r.setX(r.x() + d->leftTextMargin);
+ r.setX(r.x() + d->effectiveLeftTextMargin());
r.setY(r.y() + d->topTextMargin);
- r.setRight(r.right() - d->rightTextMargin);
+ r.setRight(r.right() - d->effectiveRightTextMargin());
r.setBottom(r.bottom() - d->bottomTextMargin);
p.setClipRect(r);
@@ -1982,6 +2074,13 @@ void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
}
}
+static inline void setActionIcon(QAction *action, const QString &name)
+{
+ const QIcon icon = QIcon::fromTheme(name);
+ if (!icon.isNull())
+ action->setIcon(icon);
+}
+
/*! This function creates the standard context menu which is shown
when the user clicks on the line edit with the right mouse
button. It is called from the default contextMenuEvent() handler.
@@ -1998,10 +2097,12 @@ QMenu *QLineEdit::createStandardContextMenu()
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
action->setEnabled(d->control->isUndoAvailable());
+ setActionIcon(action, QStringLiteral("edit-undo"));
connect(action, SIGNAL(triggered()), SLOT(undo()));
action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
action->setEnabled(d->control->isRedoAvailable());
+ setActionIcon(action, QStringLiteral("edit-redo"));
connect(action, SIGNAL(triggered()), SLOT(redo()));
popup->addSeparator();
@@ -2012,17 +2113,20 @@ QMenu *QLineEdit::createStandardContextMenu()
action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
&& d->control->echoMode() == QLineEdit::Normal);
+ setActionIcon(action, QStringLiteral("edit-cut"));
connect(action, SIGNAL(triggered()), SLOT(cut()));
}
action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
action->setEnabled(d->control->hasSelectedText()
&& d->control->echoMode() == QLineEdit::Normal);
+ setActionIcon(action, QStringLiteral("edit-copy"));
connect(action, SIGNAL(triggered()), SLOT(copy()));
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty());
+ setActionIcon(action, QStringLiteral("edit-paste"));
connect(action, SIGNAL(triggered()), SLOT(paste()));
}
#endif
@@ -2030,6 +2134,7 @@ QMenu *QLineEdit::createStandardContextMenu()
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("Delete"));
action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
+ setActionIcon(action, QStringLiteral("edit-delete"));
connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
}
@@ -2069,8 +2174,15 @@ void QLineEdit::changeEvent(QEvent *ev)
initStyleOption(&opt);
d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
}
+ d->m_iconSize = QSize();
update();
break;
+ case QEvent::LayoutDirectionChange:
+ foreach (const QLineEditPrivate::SideWidgetEntry &e, d->trailingSideWidgets) // Refresh icon to show arrow in right direction.
+ if (e.flags & QLineEditPrivate::SideWidgetClearButton)
+ static_cast<QLineEditIconButton *>(e.widget)->setIcon(d->clearButtonIcon());
+ d->positionSideWidgets();
+ break;
default:
break;
}
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
index e2b944314b..3d52863db2 100644
--- a/src/widgets/widgets/qlineedit.h
+++ b/src/widgets/widgets/qlineedit.h
@@ -59,12 +59,14 @@ class QCompleter;
class QStyleOptionFrame;
class QAbstractSpinBox;
class QDateTimeEdit;
+class QIcon;
+class QToolButton;
class Q_WIDGETS_EXPORT QLineEdit : public QWidget
{
Q_OBJECT
- Q_ENUMS(EchoMode)
+ Q_ENUMS(ActionPosition EchoMode)
Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true)
Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
@@ -83,8 +85,13 @@ class Q_WIDGETS_EXPORT QLineEdit : public QWidget
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle)
-
+ Q_PROPERTY(bool clearButtonEnabled READ isClearButtonEnabled WRITE setClearButtonEnabled)
public:
+ enum ActionPosition {
+ LeadingPosition,
+ TrailingPosition
+ };
+
explicit QLineEdit(QWidget* parent=0);
explicit QLineEdit(const QString &, QWidget* parent=0);
~QLineEdit();
@@ -102,6 +109,9 @@ public:
void setFrame(bool);
bool hasFrame() const;
+ void setClearButtonEnabled(bool enable);
+ bool isClearButtonEnabled() const;
+
enum EchoMode { Normal, NoEcho, Password, PasswordEchoOnEdit };
EchoMode echoMode() const;
void setEchoMode(EchoMode);
@@ -164,6 +174,16 @@ public:
void getTextMargins(int *left, int *top, int *right, int *bottom) const;
QMargins textMargins() const;
+#ifdef Q_NO_USING_KEYWORD
+ inline void addAction(QAction *action)
+ { QWidget::addAction(action); }
+#else
+ using QWidget::addAction;
+#endif
+
+ void addAction(QAction *action, ActionPosition position);
+ QAction *addAction(const QIcon &icon, ActionPosition position);
+
public Q_SLOTS:
void setText(const QString &);
void clear();
@@ -240,6 +260,7 @@ private:
#endif
Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &))
+ Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString &))
};
#endif // QT_NO_LINEEDIT
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 1999216e65..99d6d0b8d9 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -44,8 +44,10 @@
#ifndef QT_NO_LINEEDIT
+#include "qvariant.h"
#include "qabstractitemview.h"
#include "qdrag.h"
+#include "qwidgetaction.h"
#include "qclipboard.h"
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
@@ -53,6 +55,7 @@
#ifndef QT_NO_IM
#include "qinputmethod.h"
#include "qlist.h"
+#include <qpropertyanimation.h>
#endif
QT_BEGIN_NAMESPACE
@@ -219,9 +222,9 @@ QRect QLineEditPrivate::adjustedContentsRect() const
QStyleOptionFrameV2 opt;
q->initStyleOption(&opt);
QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
- r.setX(r.x() + leftTextMargin);
+ r.setX(r.x() + effectiveLeftTextMargin());
r.setY(r.y() + topTextMargin);
- r.setRight(r.right() - rightTextMargin);
+ r.setRight(r.right() - effectiveRightTextMargin());
r.setBottom(r.bottom() - bottomTextMargin);
return r;
}
@@ -297,6 +300,170 @@ void QLineEditPrivate::drag()
#endif // QT_NO_DRAGANDDROP
+QLineEditIconButton::QLineEditIconButton(QWidget *parent)
+ : QToolButton(parent)
+ , m_opacity(0)
+{
+#ifndef QT_NO_CURSOR
+ setCursor(Qt::ArrowCursor);
+#endif
+ setFocusPolicy(Qt::NoFocus);
+}
+
+void QLineEditIconButton::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ // Note isDown should really use the active state but in most styles
+ // this has no proper feedback
+ QIcon::Mode state = QIcon::Disabled;
+ if (isEnabled())
+ state = isDown() ? QIcon::Selected : QIcon::Normal;
+ const QPixmap iconPixmap = icon().pixmap(QSize(IconButtonSize, IconButtonSize),
+ state, QIcon::Off);
+ QRect pixmapRect = QRect(0, 0, iconPixmap.width(), iconPixmap.height());
+ pixmapRect.moveCenter(rect().center());
+ painter.setOpacity(m_opacity);
+ painter.drawPixmap(pixmapRect, iconPixmap);
+}
+
+void QLineEditIconButton::setOpacity(qreal value)
+{
+ if (!qFuzzyCompare(m_opacity, value)) {
+ m_opacity = value;
+ update();
+ }
+}
+
+void QLineEditIconButton::startOpacityAnimation(qreal endValue)
+{
+ QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"));
+ animation->setDuration(160);
+ animation->setEndValue(endValue);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+}
+
+void QLineEditPrivate::_q_textChanged(const QString &text)
+{
+ if (hasSideWidgets()) {
+ const int newTextSize = text.size();
+ if (!newTextSize || !lastTextSize) {
+ lastTextSize = newTextSize;
+ const bool fadeIn = newTextSize > 0;
+ foreach (const SideWidgetEntry &e, leadingSideWidgets) {
+ if (e.flags & SideWidgetFadeInWithText)
+ static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
+ }
+ foreach (const SideWidgetEntry &e, trailingSideWidgets) {
+ if (e.flags & SideWidgetFadeInWithText)
+ static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
+ }
+ }
+ }
+}
+
+QSize QLineEditPrivate::iconSize() const
+{
+ if (!m_iconSize.isValid()) // This might require style-specific handling (pixel metric).
+ m_iconSize = QSize(QLineEditIconButton::IconButtonSize + 6, QLineEditIconButton::IconButtonSize + 2);
+ return m_iconSize;
+}
+
+QIcon QLineEditPrivate::clearButtonIcon() const
+{
+ Q_Q(const QLineEdit);
+ QStyleOptionFrameV2 styleOption;
+ q->initStyleOption(&styleOption);
+ return QIcon(q->style()->standardPixmap(QStyle::SP_LineEditClearButton, &styleOption, q));
+}
+
+void QLineEditPrivate::positionSideWidgets()
+{
+ Q_Q(QLineEdit);
+ if (hasSideWidgets()) {
+ const QRect contentRect = q->rect();
+ const QSize iconSize = QLineEditPrivate::iconSize();
+ const int delta = QLineEditIconButton::IconMargin + iconSize.width();
+ QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize);
+ foreach (const SideWidgetEntry &e, leftSideWidgetList()) {
+ e.widget->setGeometry(widgetGeometry);
+ widgetGeometry.moveLeft(widgetGeometry.left() + delta);
+ }
+ widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin);
+ foreach (const SideWidgetEntry &e, rightSideWidgetList()) {
+ e.widget->setGeometry(widgetGeometry);
+ widgetGeometry.moveLeft(widgetGeometry.left() - delta);
+ }
+ }
+}
+
+QLineEditPrivate::PositionIndexPair QLineEditPrivate::findSideWidget(const QAction *a) const
+{
+ for (int i = 0; i < leadingSideWidgets.size(); ++i) {
+ if (a == leadingSideWidgets.at(i).action)
+ return PositionIndexPair(QLineEdit::LeadingPosition, i);
+ }
+ for (int i = 0; i < trailingSideWidgets.size(); ++i) {
+ if (a == trailingSideWidgets.at(i).action)
+ return PositionIndexPair(QLineEdit::TrailingPosition, i);
+ }
+ return PositionIndexPair(QLineEdit::LeadingPosition, -1);
+}
+
+QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition position, int flags)
+{
+ Q_Q(QLineEdit);
+ if (!newAction)
+ return 0;
+ QWidget *w = 0;
+ // Store flags about QWidgetAction here since removeAction() may be called from ~QAction,
+ // in which a qobject_cast<> no longer works.
+ if (QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(newAction)) {
+ if ((w = widgetAction->requestWidget(q)))
+ flags |= SideWidgetCreatedByWidgetAction;
+ }
+ if (!w) {
+ QLineEditIconButton *toolButton = new QLineEditIconButton(q);
+ toolButton->setIcon(newAction->icon());
+ toolButton->setOpacity(lastTextSize > 0 || !(flags & SideWidgetFadeInWithText) ? 1 : 0);
+ if (flags & SideWidgetClearButton)
+ QObject::connect(toolButton, SIGNAL(clicked()), q, SLOT(clear()));
+ toolButton->setDefaultAction(newAction);
+ w = toolButton;
+ }
+ if (!hasSideWidgets()) { // initial setup.
+ QObject::connect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
+ lastTextSize = q->text().size();
+ }
+ // If there is a 'before' action, it takes preference
+ PositionIndexPair positionIndex = before ? findSideWidget(before) : PositionIndexPair(position, -1);
+ SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets;
+ if (positionIndex.second < 0)
+ positionIndex.second = list.size();
+ list.insert(positionIndex.second, SideWidgetEntry(w, newAction, flags));
+ positionSideWidgets();
+ w->show();
+ return w;
+}
+
+void QLineEditPrivate::removeAction(const QActionEvent *e)
+{
+ Q_Q(QLineEdit);
+ QAction *action = e->action();
+ const PositionIndexPair positionIndex = findSideWidget(action);
+ if (positionIndex.second == -1)
+ return;
+ SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets;
+ SideWidgetEntry entry = list.takeAt(positionIndex.second);
+ if (entry.flags & SideWidgetCreatedByWidgetAction)
+ static_cast<QWidgetAction *>(entry.action)->releaseWidget(entry.widget);
+ else
+ delete entry.widget;
+ positionSideWidgets();
+ if (!hasSideWidgets()) // Last widget, remove connection
+ QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
+ q->update();
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index 4eb35b7dc6..8fe45972ff 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -58,7 +58,9 @@
#ifndef QT_NO_LINEEDIT
#include "private/qwidget_p.h"
#include "QtWidgets/qlineedit.h"
+#include "QtWidgets/qtoolbutton.h"
#include "QtGui/qtextlayout.h"
+#include "QtGui/qicon.h"
#include "QtWidgets/qstyleoption.h"
#include "QtCore/qbasictimer.h"
#include "QtWidgets/qcompleter.h"
@@ -69,16 +71,55 @@
QT_BEGIN_NAMESPACE
+// QLineEditIconButton: This is a simple helper class that represents clickable icons that fade in with text
+
+class QLineEditIconButton : public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
+public:
+ enum { IconMargin = 4, IconButtonSize = 16 };
+
+ explicit QLineEditIconButton(QWidget *parent = 0);
+
+ qreal opacity() const { return m_opacity; }
+ void setOpacity(qreal value);
+ void animateShow(bool visible) { startOpacityAnimation(visible ? 1.0 : 0.0); }
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ void startOpacityAnimation(qreal endValue);
+
+ qreal m_opacity;
+};
+
class Q_AUTOTEST_EXPORT QLineEditPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QLineEdit)
public:
+ enum SideWidgetFlag {
+ SideWidgetFadeInWithText = 0x1,
+ SideWidgetCreatedByWidgetAction = 0x2,
+ SideWidgetClearButton = 0x4
+ };
+
+ struct SideWidgetEntry {
+ SideWidgetEntry(QWidget *w = 0, QAction *a = 0, int _flags = 0) : widget(w), action(a), flags(_flags) {}
+
+ QWidget *widget;
+ QAction *action;
+ int flags;
+ };
+ typedef QList<SideWidgetEntry> SideWidgetEntryList;
QLineEditPrivate()
: control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
alignment(Qt::AlignLeading | Qt::AlignVCenter),
- leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
+ leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0),
+ lastTextSize(0)
{
}
@@ -145,15 +186,50 @@ public:
QBasicTimer dndTimer;
void drag();
#endif
+ void _q_textChanged(const QString &);
- int leftTextMargin;
+ int leftTextMargin; // use effectiveLeftTextMargin() in case of icon.
int topTextMargin;
- int rightTextMargin;
+ int rightTextMargin; // use effectiveRightTextMargin() in case of icon.
int bottomTextMargin;
QString placeholderText;
+
+ QWidget *addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition, int flags = 0);
+ void removeAction(const QActionEvent *e);
+ QSize iconSize() const;
+ QIcon clearButtonIcon() const;
+ void positionSideWidgets();
+ inline bool hasSideWidgets() const { return !leadingSideWidgets.isEmpty() || !trailingSideWidgets.isEmpty(); }
+ inline const SideWidgetEntryList &leftSideWidgetList() const
+ { return q_func()->layoutDirection() == Qt::LeftToRight ? leadingSideWidgets : trailingSideWidgets; }
+ inline const SideWidgetEntryList &rightSideWidgetList() const
+ { return q_func()->layoutDirection() == Qt::LeftToRight ? trailingSideWidgets : leadingSideWidgets; }
+
+ int effectiveLeftTextMargin() const;
+ int effectiveRightTextMargin() const;
+
+private:
+ typedef QPair<QLineEdit::ActionPosition, int> PositionIndexPair;
+
+ PositionIndexPair findSideWidget(const QAction *a) const;
+
+ SideWidgetEntryList leadingSideWidgets;
+ SideWidgetEntryList trailingSideWidgets;
+ int lastTextSize;
+ mutable QSize m_iconSize;
};
+inline int QLineEditPrivate::effectiveLeftTextMargin() const
+{
+ return leftTextMargin + leftSideWidgetList().size() * (QLineEditIconButton::IconMargin + iconSize().width());
+}
+
+inline int QLineEditPrivate::effectiveRightTextMargin() const
+{
+ return rightTextMargin + rightSideWidgetList().size() * (QLineEditIconButton::IconMargin + iconSize().width());
+}
+
#endif // QT_NO_LINEEDIT
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 13c9bf8deb..fd94dadac6 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -178,6 +178,8 @@
#include <qmath.h>
#include <private/qlayoutengine_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace QMdi;
@@ -465,9 +467,9 @@ void MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QList<QRe
}
QList<int> xlist = xset.values();
- qSort(xlist.begin(), xlist.end());
+ std::sort(xlist.begin(), xlist.end());
QList<int> ylist = yset.values();
- qSort(ylist.begin(), ylist.end());
+ std::sort(ylist.begin(), ylist.end());
foreach (int y, ylist)
foreach (int x, xlist)
diff --git a/src/widgets/widgets/qpushbutton_p.h b/src/widgets/widgets/qpushbutton_p.h
index 93069d295f..142df04825 100644
--- a/src/widgets/widgets/qpushbutton_p.h
+++ b/src/widgets/widgets/qpushbutton_p.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef QPUSHBUTTON_P_H
+#define QPUSHBUTTON_P_H
+
#include "private/qabstractbutton_p.h"
//
@@ -88,3 +91,5 @@ public:
};
QT_END_NAMESPACE
+
+#endif // QPUSHBUTTON_P_H
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index 93c335c56b..2a6d4620d7 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -407,6 +407,18 @@ QSize QScrollArea::sizeHint() const
return sz.boundedTo(QSize(36 * h, 24 * h));
}
+/*!
+ \reimp
+ */
+QSize QScrollArea::viewportSizeHint() const
+{
+ Q_D(const QScrollArea);
+ if (d->widget) {
+ return d->resizable ? d->widget->sizeHint() : d->widget->size();
+ }
+ const int h = fontMetrics().height();
+ return QSize(6 * h, 4 * h);
+}
/*!
diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h
index 576c9bc9e0..70af5fbbd7 100644
--- a/src/widgets/widgets/qscrollarea.h
+++ b/src/widgets/widgets/qscrollarea.h
@@ -69,6 +69,8 @@ public:
void setWidgetResizable(bool resizable);
QSize sizeHint() const;
+ QSize viewportSizeHint() const;
+
bool focusNextPrevChild(bool next);
Qt::Alignment alignment() const;
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index e1e2723a2d..05b8935bb5 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -510,6 +510,11 @@ void QScrollBar::wheelEvent(QWheelEvent *event)
Q_D(QScrollBar);
if (d->scrollByDelta(event->orientation(), event->modifiers(), delta))
event->accept();
+
+ if (event->phase() == Qt::ScrollBegin)
+ d->setTransient(false);
+ else if (event->phase() == Qt::ScrollEnd)
+ d->setTransient(true);
}
#endif
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 0ce5473ad8..bf4e130d4e 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -78,6 +78,8 @@ public:
q->setInputMethodHints(Qt::ImhDigitsOnly);
setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
}
+
+ int displayIntegerBase;
};
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
@@ -425,6 +427,38 @@ void QSpinBox::setRange(int minimum, int maximum)
}
/*!
+ \property QSpinBox::displayIntegerBase
+
+ \brief the base used to display the value of the spin box
+
+ The default displayIntegerBase value is 10.
+
+ \sa textFromValue(), valueFromText()
+ \since 5.2
+*/
+
+int QSpinBox::displayIntegerBase() const
+{
+ Q_D(const QSpinBox);
+ return d->displayIntegerBase;
+}
+
+void QSpinBox::setDisplayIntegerBase(int base)
+{
+ Q_D(QSpinBox);
+ // Falls back to base 10 on invalid bases (like QString)
+ if (base < 2 || base > 36) {
+ qWarning("QSpinBox::setDisplayIntegerBase: Invalid base (%d)", base);
+ base = 10;
+ }
+
+ if (base != d->displayIntegerBase) {
+ d->displayIntegerBase = base;
+ d->updateEdit();
+ }
+}
+
+/*!
This virtual function is used by the spin box whenever it needs to
display the given \a value. The default implementation returns a
string containing \a value printed in the standard way using
@@ -444,9 +478,18 @@ void QSpinBox::setRange(int minimum, int maximum)
QString QSpinBox::textFromValue(int value) const
{
- QString str = locale().toString(value);
- if (qAbs(value) >= 1000 || value == INT_MIN) {
- str.remove(locale().groupSeparator());
+ Q_D(const QSpinBox);
+ QString str;
+
+ if (d->displayIntegerBase != 10) {
+ str = QString::number(qAbs(value), d->displayIntegerBase);
+ if (value < 0)
+ str.prepend('-');
+ } else {
+ str = locale().toString(value);
+ if (qAbs(value) >= 1000 || value == INT_MIN) {
+ str.remove(locale().groupSeparator());
+ }
}
return str;
@@ -926,6 +969,7 @@ QSpinBoxPrivate::QSpinBoxPrivate()
minimum = QVariant((int)0);
maximum = QVariant((int)99);
value = minimum;
+ displayIntegerBase = 10;
singleStep = QVariant((int)1);
type = QVariant::Int;
}
@@ -1003,11 +1047,15 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100
} else {
bool ok = false;
- num = locale.toInt(copy, &ok);
- if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {
- QString copy2 = copy;
- copy2.remove(locale.groupSeparator());
- num = locale.toInt(copy2, &ok);
+ if (displayIntegerBase != 10) {
+ num = copy.toInt(&ok, displayIntegerBase);
+ } else {
+ num = locale.toInt(copy, &ok);
+ if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {
+ QString copy2 = copy;
+ copy2.remove(locale.groupSeparator());
+ num = locale.toInt(copy2, &ok);
+ }
}
QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
if (!ok) {
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
index 4963f87a1a..98e809e141 100644
--- a/src/widgets/widgets/qspinbox.h
+++ b/src/widgets/widgets/qspinbox.h
@@ -61,6 +61,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox
Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
+ Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase)
public:
explicit QSpinBox(QWidget *parent = 0);
@@ -87,6 +88,8 @@ public:
void setRange(int min, int max);
+ int displayIntegerBase() const;
+ void setDisplayIntegerBase(int base);
protected:
bool event(QEvent *event);
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index 746c02e4e2..b2a0d3f8b8 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -200,7 +200,7 @@ void QSplashScreen::repaint()
is kept up to date with what your application is doing (e.g.,
loading files).
- \sa Qt::Alignment, clearMessage()
+ \sa Qt::Alignment, clearMessage(), message()
*/
void QSplashScreen::showMessage(const QString &message, int alignment,
const QColor &color)
@@ -214,6 +214,20 @@ void QSplashScreen::showMessage(const QString &message, int alignment,
}
/*!
+ \since 5.2
+
+ Returns the message that is currently displayed on the splash screen.
+
+ \sa showMessage(), clearMessage()
+*/
+
+QString QSplashScreen::message() const
+{
+ Q_D(const QSplashScreen);
+ return d->currStatus;
+}
+
+/*!
Removes the message being displayed on the splash screen
\sa showMessage()
diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h
index a1af8e45ef..e675c2e7af 100644
--- a/src/widgets/widgets/qsplashscreen.h
+++ b/src/widgets/widgets/qsplashscreen.h
@@ -63,6 +63,7 @@ public:
const QPixmap pixmap() const;
void finish(QWidget *w);
void repaint();
+ QString message() const;
public Q_SLOTS:
void showMessage(const QString &message, int alignment = Qt::AlignLeft,
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 031763b80c..1f3646ea6e 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1404,19 +1404,24 @@ int QSplitter::closestLegalPosition(int pos, int index)
\property QSplitter::opaqueResize
\brief whether resizing is opaque
- Opaque resizing is on by default.
+ The default resize behavior is style dependent (determined by the
+ SH_Splitter_OpaqueResize style hint). However, you can override it
+ by calling setOpaqueResize()
+
+ \sa QStyle::StyleHint
*/
bool QSplitter::opaqueResize() const
{
Q_D(const QSplitter);
- return d->opaque;
+ return d->opaqueResizeSet ? d->opaque : style()->styleHint(QStyle::SH_Splitter_OpaqueResize, 0, this);
}
void QSplitter::setOpaqueResize(bool on)
{
Q_D(QSplitter);
+ d->opaqueResizeSet = true;
d->opaque = on;
}
@@ -1589,7 +1594,7 @@ static const qint32 SplitterMagic = 0xff;
QByteArray QSplitter::saveState() const
{
Q_D(const QSplitter);
- int version = 0;
+ int version = 1;
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
@@ -1605,6 +1610,7 @@ QByteArray QSplitter::saveState() const
stream << qint32(handleWidth());
stream << opaqueResize();
stream << qint32(orientation());
+ stream << d->opaqueResizeSet;
return data;
}
@@ -1627,7 +1633,7 @@ QByteArray QSplitter::saveState() const
bool QSplitter::restoreState(const QByteArray &state)
{
Q_D(QSplitter);
- int version = 0;
+ int version = 1;
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
QList<int> list;
@@ -1638,7 +1644,7 @@ bool QSplitter::restoreState(const QByteArray &state)
stream >> marker;
stream >> v;
- if (marker != SplitterMagic || v != version)
+ if (marker != SplitterMagic || v > version)
return false;
stream >> list;
@@ -1657,6 +1663,9 @@ bool QSplitter::restoreState(const QByteArray &state)
setOrientation(Qt::Orientation(i));
d->doResize();
+ if (v >= 1)
+ stream >> d->opaqueResizeSet;
+
return true;
}
diff --git a/src/widgets/widgets/qsplitter_p.h b/src/widgets/widgets/qsplitter_p.h
index f1e050b8f6..0d0e134f58 100644
--- a/src/widgets/widgets/qsplitter_p.h
+++ b/src/widgets/widgets/qsplitter_p.h
@@ -83,7 +83,7 @@ class QSplitterPrivate : public QFramePrivate
Q_DECLARE_PUBLIC(QSplitter)
public:
QSplitterPrivate() : rubberBand(0), opaque(true), firstShow(true),
- childrenCollapsible(true), compatMode(false), handleWidth(-1), blockChildAdd(false) {}
+ childrenCollapsible(true), compatMode(false), handleWidth(-1), blockChildAdd(false), opaqueResizeSet(false) {}
QPointer<QRubberBand> rubberBand;
mutable QList<QSplitterLayoutStruct *> list;
@@ -94,6 +94,7 @@ public:
bool compatMode : 8;
int handleWidth;
bool blockChildAdd;
+ bool opaqueResizeSet;
inline int pick(const QPoint &pos) const
{ return orient == Qt::Horizontal ? pos.x() : pos.y(); }
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index b975035dcf..aa7677869c 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -329,6 +329,26 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const
\sa moveTab()
*/
+/*!
+ \fn void QTabBar::tabBarClicked(int index)
+
+ This signal is emitted when user clicks on a tab at an \a index.
+
+ \a index is the index of a clicked tab, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
+/*!
+ \fn void QTabBar::tabBarDoubleClicked(int index)
+
+ This signal is emitted when the user double clicks on a tab at \a index.
+
+ \a index refers to the tab clicked, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
int QTabBarPrivate::extraWidth() const
{
Q_Q(const QTabBar);
@@ -1703,11 +1723,37 @@ void QTabBarPrivate::moveTab(int index, int offset)
q_func()->update();
}
+
+/*!
+ \reimp
+*/
+void QTabBar::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_D(QTabBar);
+
+ const QPoint pos = event->pos();
+ const bool isEventInCornerButtons = (!d->leftB->isHidden() && d->leftB->geometry().contains(pos))
+ || (!d->rightB->isHidden() && d->rightB->geometry().contains(pos));
+ if (!isEventInCornerButtons) {
+ const int index = tabAt(pos);
+ emit tabBarDoubleClicked(index);
+ }
+}
+
/*!\reimp
*/
void QTabBar::mousePressEvent(QMouseEvent *event)
{
Q_D(QTabBar);
+
+ const QPoint pos = event->pos();
+ const bool isEventInCornerButtons = (!d->leftB->isHidden() && d->leftB->geometry().contains(pos))
+ || (!d->rightB->isHidden() && d->rightB->geometry().contains(pos));
+ if (!isEventInCornerButtons) {
+ const int index = d->indexAtPos(pos);
+ emit tabBarClicked(index);
+ }
+
if (event->button() != Qt::LeftButton) {
event->ignore();
return;
diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h
index 72c19ab520..1f7b8f6b03 100644
--- a/src/widgets/widgets/qtabbar.h
+++ b/src/widgets/widgets/qtabbar.h
@@ -173,6 +173,8 @@ Q_SIGNALS:
void currentChanged(int index);
void tabCloseRequested(int index);
void tabMoved(int from, int to);
+ void tabBarClicked(int index);
+ void tabBarDoubleClicked(int index);
protected:
virtual QSize tabSizeHint(int index) const;
@@ -186,6 +188,7 @@ protected:
void showEvent(QShowEvent *);
void hideEvent(QHideEvent *);
void paintEvent(QPaintEvent *);
+ void mouseDoubleClickEvent(QMouseEvent *);
void mousePressEvent (QMouseEvent *);
void mouseMoveEvent (QMouseEvent *);
void mouseReleaseEvent (QMouseEvent *);
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 7468144146..8c6e70b8d7 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -138,6 +138,10 @@ public:
} *animation;
void startAnimation(QTabBarPrivate *priv, int duration) {
+ if (!priv->isAnimated()) {
+ priv->moveTabFinished(priv->tabList.indexOf(*this));
+ return;
+ }
if (!animation)
animation = new TabBarAnimation(this, priv);
animation->setStartValue(dragOffset);
@@ -162,6 +166,7 @@ public:
int indexAtPos(const QPoint &p) const;
+ inline bool isAnimated() const { Q_Q(const QTabBar); return q->style()->styleHint(QStyle::SH_Widget_Animate, 0, q); }
inline bool validIndex(int index) const { return index >= 0 && index < tabList.count(); }
void setCurrentNextEnabledIndex(int offset);
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index 4df55e2537..9d14c01490 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -172,6 +172,26 @@ QT_BEGIN_NAMESPACE
\sa setTabsClosable()
*/
+/*!
+ \fn void QTabWidget::tabBarClicked(int index)
+
+ This signal is emitted when user clicks on a tab at an \a index.
+
+ \a index refers to the tab clicked, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
+/*!
+ \fn void QTabWidget::tabBarDoubleClicked(int index)
+
+ This signal is emitted when the user double clicks on a tab at an \a index.
+
+ \a index is the index of a clicked tab, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
class QTabWidgetPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QTabWidget)
@@ -693,6 +713,10 @@ void QTabWidget::setTabBar(QTabBar* tb)
this, SLOT(_q_showTab(int)));
connect(d->tabs, SIGNAL(tabMoved(int,int)),
this, SLOT(_q_tabMoved(int,int)));
+ connect(d->tabs, SIGNAL(tabBarClicked(int)),
+ this, SIGNAL(tabBarClicked(int)));
+ connect(d->tabs, SIGNAL(tabBarDoubleClicked(int)),
+ this, SIGNAL(tabBarDoubleClicked(int)));
if (d->tabs->tabsClosable())
connect(d->tabs, SIGNAL(tabCloseRequested(int)),
this, SIGNAL(tabCloseRequested(int)));
diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h
index 1a1eb2ef2b..83c2e31d28 100644
--- a/src/widgets/widgets/qtabwidget.h
+++ b/src/widgets/widgets/qtabwidget.h
@@ -151,6 +151,8 @@ public Q_SLOTS:
Q_SIGNALS:
void currentChanged(int index);
void tabCloseRequested(int index);
+ void tabBarClicked(int index);
+ void tabBarDoubleClicked(int index);
protected:
virtual void tabInserted(int index);
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 4b3bf6de65..4e0c682493 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -773,6 +773,35 @@ QTextDocument *QTextEdit::document() const
}
/*!
+ \since 5.2
+
+ \property QTextEdit::placeholderText
+ \brief the editor placeholder text
+
+ Setting this property makes the editor display a grayed-out
+ placeholder text as long as the document() is empty.
+
+ By default, this property contains an empty string.
+
+ \sa document()
+*/
+QString QTextEdit::placeholderText() const
+{
+ Q_D(const QTextEdit);
+ return d->placeholderText;
+}
+
+void QTextEdit::setPlaceholderText(const QString &placeholderText)
+{
+ Q_D(QTextEdit);
+ if (d->placeholderText != placeholderText) {
+ d->placeholderText = placeholderText;
+ if (d->control->document()->isEmpty())
+ d->viewport->update();
+ }
+}
+
+/*!
Sets the visible \a cursor.
*/
void QTextEdit::setTextCursor(const QTextCursor &cursor)
@@ -1499,6 +1528,13 @@ void QTextEdit::paintEvent(QPaintEvent *e)
Q_D(QTextEdit);
QPainter p(d->viewport);
d->paint(&p, e);
+ if (!d->placeholderText.isEmpty() && d->control->document()->isEmpty()) {
+ QColor col = palette().text().color();
+ col.setAlpha(128);
+ p.setPen(col);
+ const int margin = int(document()->documentMargin());
+ p.drawText(d->viewport->rect().adjusted(margin, margin, -margin, -margin), Qt::AlignTop | Qt::TextWordWrap, d->placeholderText);
+ }
}
void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h
index e1471848e7..06ec5fb889 100644
--- a/src/widgets/widgets/qtextedit.h
+++ b/src/widgets/widgets/qtextedit.h
@@ -85,6 +85,7 @@ class Q_WIDGETS_EXPORT QTextEdit : public QAbstractScrollArea
Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
Q_PROPERTY(QTextDocument *document READ document WRITE setDocument DESIGNABLE false)
+ Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
public:
enum LineWrapMode {
NoWrap,
@@ -108,6 +109,9 @@ public:
void setDocument(QTextDocument *document);
QTextDocument *document() const;
+ void setPlaceholderText(const QString &placeholderText);
+ QString placeholderText() const;
+
void setTextCursor(const QTextCursor &cursor);
QTextCursor textCursor() const;
diff --git a/src/widgets/widgets/qtextedit_p.h b/src/widgets/widgets/qtextedit_p.h
index 1ce68dc23e..daa6eb5ed0 100644
--- a/src/widgets/widgets/qtextedit_p.h
+++ b/src/widgets/widgets/qtextedit_p.h
@@ -130,6 +130,8 @@ public:
QString anchorToScrollToWhenVisible;
+ QString placeholderText;
+
#ifdef QT_KEYPAD_NAVIGATION
QBasicTimer deleteAllTimer;
#endif
diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp
index bbd96ca29a..1209ade536 100644
--- a/src/widgets/widgets/qwidgetanimator.cpp
+++ b/src/widgets/widgets/qwidgetanimator.cpp
@@ -91,24 +91,28 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
#ifndef QT_NO_ANIMATION
- AnimationMap::const_iterator it = m_animation_map.constFind(widget);
- if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
- return;
+ //If the QStyle has animations, animate
+ if (widget->style()->styleHint(QStyle::SH_Widget_Animate, 0, widget)) {
+ AnimationMap::const_iterator it = m_animation_map.constFind(widget);
+ if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
+ return;
- QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
- anim->setDuration(animate ? 200 : 0);
- anim->setEasingCurve(QEasingCurve::InOutQuad);
- anim->setEndValue(final_geometry);
- m_animation_map[widget] = anim;
- connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
- anim->start(QPropertyAnimation::DeleteWhenStopped);
-#else
+ QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
+ anim->setDuration(animate ? 200 : 0);
+ anim->setEasingCurve(QEasingCurve::InOutQuad);
+ anim->setEndValue(final_geometry);
+ m_animation_map[widget] = anim;
+ connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
+ anim->start(QPropertyAnimation::DeleteWhenStopped);
+ } else
+#endif //QT_NO_ANIMATION
+ {
//we do it in one shot
widget->setGeometry(final_geometry);
#ifndef QT_NO_MAINWINDOW
m_mainWindowLayout->animationFinished(widget);
#endif //QT_NO_MAINWINDOW
-#endif //QT_NO_ANIMATION
+ }
}
bool QWidgetAnimator::animating() const
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 9212f942c5..d10001a305 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -427,7 +427,7 @@ bool QWidgetLineControl::fixup() // this function assumes that validate currentl
m_validator->fixup(textCopy);
if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
if (textCopy != m_text || cursorCopy != m_cursor)
- internalSetText(textCopy, cursorCopy);
+ internalSetText(textCopy, cursorCopy, false);
return true;
}
}
@@ -672,7 +672,7 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
if (m_validInput) {
if (m_text != textCopy) {
- internalSetText(textCopy, cursorCopy);
+ internalSetText(textCopy, cursorCopy, false);
return true;
}
m_cursor = cursorCopy;
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index de06d4454a..0255183c87 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2126,6 +2126,13 @@ void QWidgetTextControlPrivate::editFocusEvent(QEvent *e)
#endif
#ifndef QT_NO_CONTEXTMENU
+static inline void setActionIcon(QAction *action, const QString &name)
+{
+ const QIcon icon = QIcon::fromTheme(name);
+ if (!icon.isNull())
+ action->setIcon(icon);
+}
+
QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget *parent)
{
Q_D(QWidgetTextControl);
@@ -2145,17 +2152,21 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
if (d->interactionFlags & Qt::TextEditable) {
a = menu->addAction(tr("&Undo") + ACCEL_KEY(QKeySequence::Undo), this, SLOT(undo()));
a->setEnabled(d->doc->isUndoAvailable());
+ setActionIcon(a, QStringLiteral("edit-undo"));
a = menu->addAction(tr("&Redo") + ACCEL_KEY(QKeySequence::Redo), this, SLOT(redo()));
a->setEnabled(d->doc->isRedoAvailable());
+ setActionIcon(a, QStringLiteral("edit-redo"));
menu->addSeparator();
a = menu->addAction(tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut), this, SLOT(cut()));
a->setEnabled(d->cursor.hasSelection());
+ setActionIcon(a, QStringLiteral("edit-cut"));
}
if (showTextSelectionActions) {
a = menu->addAction(tr("&Copy") + ACCEL_KEY(QKeySequence::Copy), this, SLOT(copy()));
a->setEnabled(d->cursor.hasSelection());
+ setActionIcon(a, QStringLiteral("edit-copy"));
}
if ((d->interactionFlags & Qt::LinksAccessibleByKeyboard)
@@ -2169,9 +2180,11 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
#if !defined(QT_NO_CLIPBOARD)
a = menu->addAction(tr("&Paste") + ACCEL_KEY(QKeySequence::Paste), this, SLOT(paste()));
a->setEnabled(canPaste());
+ setActionIcon(a, QStringLiteral("edit-paste"));
#endif
a = menu->addAction(tr("Delete"), this, SLOT(_q_deleteSelected()));
a->setEnabled(d->cursor.hasSelection());
+ setActionIcon(a, QStringLiteral("edit-delete"));
}
diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf
index 4e8cf34b0c..f9c847e022 100644
--- a/src/xml/doc/qtxml.qdocconf
+++ b/src/xml/doc/qtxml.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/xml \
imagedirs += images \
../../../examples/xml/images
+
+navigation.landingpage = "Qt XML"
+navigation.cppclassespage = "Qt XML C++ Classes"
diff --git a/src/xml/doc/src/qtxml.qdoc b/src/xml/doc/src/qtxml.qdoc
index 5ffa0f7330..925e492880 100644
--- a/src/xml/doc/src/qtxml.qdoc
+++ b/src/xml/doc/src/qtxml.qdoc
@@ -29,6 +29,7 @@
\module QtXml
\title Qt XML C++ Classes
\ingroup modules
+ \qtvariable xml
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.